diff options
author | Nemanja Ivanovic <nemanja.i.ibm@gmail.com> | 2018-07-13 15:21:03 +0000 |
---|---|---|
committer | Nemanja Ivanovic <nemanja.i.ibm@gmail.com> | 2018-07-13 15:21:03 +0000 |
commit | 080c35050ef2049b65419f52a58e35c2e4fe1dc5 (patch) | |
tree | eb6879b18c1865f9a49c59de31fb154ff4055ad9 /llvm/lib/Target/PowerPC | |
parent | 06e7e5798fa4efdcbc9598427fb8ccb6942d6cb0 (diff) | |
download | bcm5719-llvm-080c35050ef2049b65419f52a58e35c2e4fe1dc5.tar.gz bcm5719-llvm-080c35050ef2049b65419f52a58e35c2e4fe1dc5.zip |
[PowerPC] Materialize more constants with CR-field set in late peephole
Revision r322373 fixed a bug in how we materialize constants when the CR-field
needs to be set.
However the fix is overly conservative. It will only do the transform if
AND-ing the input with the new constant produces the same new constant.
This is of course correct, but not necessarily required.
If there are no futher uses of the constant, the constant can be changed.
If there are no uses of the GPR result, the final result of the materialization
isn't important other than it needs to compare to zero correctly (lt, gt, eq).
Differential revision: https://reviews.llvm.org/D42109
llvm-svn: 337008
Diffstat (limited to 'llvm/lib/Target/PowerPC')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index 540d6932004..0a3b969c9c3 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -2480,8 +2480,6 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI, Is64BitLI = Opc != PPC::RLDICL_32; NewImm = InVal.getSExtValue(); SetCR = Opc == PPC::RLDICLo; - if (SetCR && (SExtImm & NewImm) != NewImm) - return false; break; } return false; @@ -2495,7 +2493,7 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI, int64_t ME = MI.getOperand(4).getImm(); APInt InVal(32, SExtImm, true); InVal = InVal.rotl(SH); - // Set the bits ( MB + 32 ) to ( ME + 32 ). + // Set the bits ( MB + 32 ) to ( ME + 32 ). uint64_t Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1); InVal &= Mask; // Can't replace negative values with an LI as that will sign-extend @@ -2509,8 +2507,6 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI, Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o; NewImm = InVal.getSExtValue(); SetCR = Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o; - if (SetCR && (SExtImm & NewImm) != NewImm) - return false; break; } return false; @@ -2536,6 +2532,33 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI, } if (ReplaceWithLI) { + // We need to be careful with CR-setting instructions we're replacing. + if (SetCR) { + // We don't know anything about uses when we're out of SSA, so only + // replace if the new immediate will be reproduced. + bool ImmChanged = (SExtImm & NewImm) != NewImm; + if (PostRA && ImmChanged) + return false; + + if (!PostRA) { + // If the defining load-immediate has no other uses, we can just replace + // the immediate with the new immediate. + if (MRI->hasOneUse(DefMI->getOperand(0).getReg())) + DefMI->getOperand(1).setImm(NewImm); + + // If we're not using the GPR result of the CR-setting instruction, we + // just need to and with zero/non-zero depending on the new immediate. + else if (MRI->use_empty(MI.getOperand(0).getReg())) { + if (NewImm) { + assert(Immediate && "Transformation converted zero to non-zero?"); + NewImm = Immediate; + } + } + else if (ImmChanged) + return false; + } + } + LLVM_DEBUG(dbgs() << "Replacing instruction:\n"); LLVM_DEBUG(MI.dump()); LLVM_DEBUG(dbgs() << "Fed by:\n"); |