diff options
author | Jonas Paulsson <jonas.paulsson@ericsson.com> | 2015-10-08 07:40:19 +0000 |
---|---|---|
committer | Jonas Paulsson <jonas.paulsson@ericsson.com> | 2015-10-08 07:40:19 +0000 |
commit | 76e39b5ce861e9ba13e69197e24a6cdd1a83c4f9 (patch) | |
tree | 3bf253b55e24826450cf0794ce4b830bca33f79a /lib/Target/SystemZ | |
parent | e6a99a2ba1c2ea7999fceb98b2aecafb84e424ca (diff) | |
download | llvm-76e39b5ce861e9ba13e69197e24a6cdd1a83c4f9.tar.gz |
[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
Diffstat (limited to 'lib/Target/SystemZ')
-rw-r--r-- | lib/Target/SystemZ/SystemZShortenInst.cpp | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/lib/Target/SystemZ/SystemZShortenInst.cpp b/lib/Target/SystemZ/SystemZShortenInst.cpp index 33aa2725a973..c2237ee0b3dd 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; |