From: Jonas Paulsson Date: Thu, 8 Oct 2015 07:40:19 +0000 (+0000) Subject: [SystemZ] Bugfix: check CC reg liveness in SystemZShortenInst. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=76e39b5ce861e9ba13e69197e24a6cdd1a83c4f9;p=oota-llvm.git [SystemZ] Bugfix: check CC reg liveness in SystemZShortenInst. The following instruction shortening transformations would introduce a definition of the CC reg, so therefore liveness of CC reg must be checked: WFADB -> ADBR WFSDB -> SDBR Also add the CC reg implicit def operand to the MI in case of change of opcode. Reviewed by Ulrich Weigand. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249665 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/SystemZ/SystemZShortenInst.cpp b/lib/Target/SystemZ/SystemZShortenInst.cpp index 33aa2725a97..c2237ee0b3d 100644 --- a/lib/Target/SystemZ/SystemZShortenInst.cpp +++ b/lib/Target/SystemZ/SystemZShortenInst.cpp @@ -40,6 +40,7 @@ private: bool shortenOn0(MachineInstr &MI, unsigned Opcode); bool shortenOn01(MachineInstr &MI, unsigned Opcode); bool shortenOn001(MachineInstr &MI, unsigned Opcode); + bool shortenOn001AddCC(MachineInstr &MI, unsigned Opcode, bool CCLive); bool shortenFPConv(MachineInstr &MI, unsigned Opcode); const SystemZInstrInfo *TII; @@ -134,6 +135,18 @@ bool SystemZShortenInst::shortenOn001(MachineInstr &MI, unsigned Opcode) { return false; } +// Calls shortenOn001 if CCLive is false. CC def operand is added in +// case of success. +bool SystemZShortenInst::shortenOn001AddCC(MachineInstr &MI, unsigned Opcode, + bool CCLive) { + if (!CCLive && shortenOn001(MI, Opcode)) { + MachineInstrBuilder(*MI.getParent()->getParent(), &MI) + .addReg(SystemZ::CC, RegState::ImplicitDefine); + return true; + } + return false; +} + // MI is a vector-style conversion instruction with the operand order: // destination, source, exact-suppress, rounding-mode. If both registers // have a 4-bit encoding then change it to Opcode, which has operand order: @@ -167,12 +180,15 @@ bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) { // Work out which words are live on exit from the block. unsigned LiveLow = 0; unsigned LiveHigh = 0; + bool CCLive = false; for (auto SI = MBB.succ_begin(), SE = MBB.succ_end(); SI != SE; ++SI) { for (const auto &LI : (*SI)->liveins()) { unsigned Reg = LI.PhysReg; assert(Reg < SystemZ::NUM_TARGET_REGS && "Invalid register number"); LiveLow |= LowGPRs[Reg]; LiveHigh |= HighGPRs[Reg]; + if (Reg == SystemZ::CC) + CCLive = true; } } @@ -191,7 +207,7 @@ bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) { break; case SystemZ::WFADB: - Changed |= shortenOn001(MI, SystemZ::ADBR); + Changed |= shortenOn001AddCC(MI, SystemZ::ADBR, CCLive); break; case SystemZ::WFDDB: @@ -230,10 +246,10 @@ bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) { Changed |= shortenOn01(MI, SystemZ::SQDBR); break; - case SystemZ::WFSDB: - Changed |= shortenOn001(MI, SystemZ::SDBR); + case SystemZ::WFSDB: { + Changed |= shortenOn001AddCC(MI, SystemZ::SDBR, CCLive); break; - + } case SystemZ::WFCDB: Changed |= shortenOn01(MI, SystemZ::CDBR); break; @@ -276,6 +292,11 @@ bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) { } LiveLow |= UsedLow; LiveHigh |= UsedHigh; + + if (MI.definesRegister(SystemZ::CC)) + CCLive = false; + if (MI.readsRegister(SystemZ::CC)) + CCLive = true; } return Changed;