From 50608bac2fe1d3eb4753b6acdac06292eae7b980 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 4 Nov 2009 08:33:14 +0000 Subject: [PATCH] RangeIsDefinedByCopyFromReg() should check for subreg_to_reg, insert_subreg, and extract_subreg as a "copy" that defines a valno. Also fixes a typo. These two issues prevent a simple subreg coalescing from happening before. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86022 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SimpleRegisterCoalescing.cpp | 28 +++++++++++++++---- .../X86/2009-11-04-SubregCoalescingBug.ll | 15 ++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index e711a06be77..b5d6b471f47 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -1369,7 +1369,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { if (SrcSubIdx) SrcSubRC = SrcRC->getSubRegisterRegClass(SrcSubIdx); assert(SrcSubRC && "Illegal subregister index"); - if (!SrcSubRC->contains(DstReg)) { + if (!SrcSubRC->contains(DstSubReg)) { DEBUG(errs() << "\tIncompatible source regclass: " << tri_->getName(DstSubReg) << " not in " << SrcSubRC->getName() << ".\n"); @@ -1834,6 +1834,25 @@ static bool InVector(VNInfo *Val, const SmallVector &V) { return std::find(V.begin(), V.end(), Val) != V.end(); } +static bool isValNoDefMove(const MachineInstr *MI, unsigned DR, unsigned SR, + const TargetInstrInfo *TII, + const TargetRegisterInfo *TRI) { + unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; + if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) + ; + else if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) { + DstReg = MI->getOperand(0).getReg(); + SrcReg = MI->getOperand(1).getReg(); + } else if (MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG || + MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) { + DstReg = MI->getOperand(0).getReg(); + SrcReg = MI->getOperand(2).getReg(); + } else + return false; + return (SrcReg == SR || TRI->isSuperRegister(SR, SrcReg)) && + (DstReg == DR || TRI->isSuperRegister(DR, DstReg)); +} + /// RangeIsDefinedByCopyFromReg - Return true if the specified live range of /// the specified live interval is defined by a copy from the specified /// register. @@ -1850,12 +1869,9 @@ bool SimpleRegisterCoalescing::RangeIsDefinedByCopyFromReg(LiveInterval &li, // It's a sub-register live interval, we may not have precise information. // Re-compute it. MachineInstr *DefMI = li_->getInstructionFromIndex(LR->start); - unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; - if (DefMI && - tii_->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) && - DstReg == li.reg && SrcReg == Reg) { + if (DefMI && isValNoDefMove(DefMI, li.reg, Reg, tii_, tri_)) { // Cache computed info. - LR->valno->def = LR->start; + LR->valno->def = LR->start; LR->valno->setCopy(DefMI); return true; } diff --git a/test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll b/test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll new file mode 100644 index 00000000000..d84b63a21be --- /dev/null +++ b/test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin11 | FileCheck %s +; rdar://7362871 + +define void @bar(i32 %b, i32 %a) nounwind optsize ssp { +entry: +; CHECK: leal 15(%rsi), %edi +; CHECK-NOT: movl +; CHECK: call _foo + %0 = add i32 %a, 15 ; [#uses=1] + %1 = zext i32 %0 to i64 ; [#uses=1] + tail call void @foo(i64 %1) nounwind + ret void +} + +declare void @foo(i64)