summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
diff options
context:
space:
mode:
authorJonas Paulsson <paulsson@linux.vnet.ibm.com>2018-01-10 09:18:17 +0000
committerJonas Paulsson <paulsson@linux.vnet.ibm.com>2018-01-10 09:18:17 +0000
commitd9dde1ac56ceb00c1b1d74707a710871b4c2be32 (patch)
treeaccf467757032f702b24f7413f860ac425939a6d /llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
parentf34d65a164acd0c2a6c29ea03d08f8136d0e8359 (diff)
downloadbcm5719-llvm-d9dde1ac56ceb00c1b1d74707a710871b4c2be32.tar.gz
bcm5719-llvm-d9dde1ac56ceb00c1b1d74707a710871b4c2be32.zip
[SystemZ] Check for legality before doing LOAD AND TEST transformations.
Since a load and test instruction treat its operands as signed, it can only replace a logical compare for EQ/NE uses. Review: Ulrich Weigand https://bugs.llvm.org/show_bug.cgi?id=35662 llvm-svn: 322161
Diffstat (limited to 'llvm/lib/Target/SystemZ/SystemZElimCompare.cpp')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZElimCompare.cpp40
1 files changed, 25 insertions, 15 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp b/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
index a8e0ba4fb15..0619a47a14d 100644
--- a/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
@@ -86,9 +86,11 @@ private:
SmallVectorImpl<MachineInstr *> &CCUsers);
bool convertToLoadAndTrap(MachineInstr &MI, MachineInstr &Compare,
SmallVectorImpl<MachineInstr *> &CCUsers);
- bool convertToLoadAndTest(MachineInstr &MI);
+ bool convertToLoadAndTest(MachineInstr &MI, MachineInstr &Compare,
+ SmallVectorImpl<MachineInstr *> &CCUsers);
bool adjustCCMasksForInstr(MachineInstr &MI, MachineInstr &Compare,
- SmallVectorImpl<MachineInstr *> &CCUsers);
+ SmallVectorImpl<MachineInstr *> &CCUsers,
+ unsigned ConvOpc = 0);
bool optimizeCompareZero(MachineInstr &Compare,
SmallVectorImpl<MachineInstr *> &CCUsers);
bool fuseCompareOperations(MachineInstr &Compare,
@@ -282,9 +284,13 @@ bool SystemZElimCompare::convertToLoadAndTrap(
// If MI is a load instruction, try to convert it into a LOAD AND TEST.
// Return true on success.
-bool SystemZElimCompare::convertToLoadAndTest(MachineInstr &MI) {
+bool SystemZElimCompare::convertToLoadAndTest(
+ MachineInstr &MI, MachineInstr &Compare,
+ SmallVectorImpl<MachineInstr *> &CCUsers) {
+
+ // Try to adjust CC masks for a LOAD AND TEST opcode that could replace MI.
unsigned Opcode = TII->getLoadAndTest(MI.getOpcode());
- if (!Opcode)
+ if (!Opcode || !adjustCCMasksForInstr(MI, Compare, CCUsers, Opcode))
return false;
MI.setDesc(TII->get(Opcode));
@@ -294,14 +300,16 @@ bool SystemZElimCompare::convertToLoadAndTest(MachineInstr &MI) {
}
// The CC users in CCUsers are testing the result of a comparison of some
-// value X against zero and we know that any CC value produced by MI
-// would also reflect the value of X. Try to adjust CCUsers so that
-// they test the result of MI directly, returning true on success.
-// Leave everything unchanged on failure.
+// value X against zero and we know that any CC value produced by MI would
+// also reflect the value of X. ConvOpc may be used to pass the transfomed
+// opcode MI will have if this succeeds. Try to adjust CCUsers so that they
+// test the result of MI directly, returning true on success. Leave
+// everything unchanged on failure.
bool SystemZElimCompare::adjustCCMasksForInstr(
MachineInstr &MI, MachineInstr &Compare,
- SmallVectorImpl<MachineInstr *> &CCUsers) {
- int Opcode = MI.getOpcode();
+ SmallVectorImpl<MachineInstr *> &CCUsers,
+ unsigned ConvOpc) {
+ int Opcode = (ConvOpc ? ConvOpc : MI.getOpcode());
const MCInstrDesc &Desc = TII->get(Opcode);
unsigned MIFlags = Desc.TSFlags;
@@ -358,9 +366,11 @@ bool SystemZElimCompare::adjustCCMasksForInstr(
}
// CC is now live after MI.
- int CCDef = MI.findRegisterDefOperandIdx(SystemZ::CC, false, true, TRI);
- assert(CCDef >= 0 && "Couldn't find CC set");
- MI.getOperand(CCDef).setIsDead(false);
+ if (!ConvOpc) {
+ int CCDef = MI.findRegisterDefOperandIdx(SystemZ::CC, false, true, TRI);
+ assert(CCDef >= 0 && "Couldn't find CC set");
+ MI.getOperand(CCDef).setIsDead(false);
+ }
// Clear any intervening kills of CC.
MachineBasicBlock::iterator MBBI = MI, MBBE = Compare;
@@ -419,7 +429,7 @@ bool SystemZElimCompare::optimizeCompareZero(
}
}
// Try to eliminate Compare by reusing a CC result from MI.
- if ((!CCRefs && convertToLoadAndTest(MI)) ||
+ if ((!CCRefs && convertToLoadAndTest(MI, Compare, CCUsers)) ||
(!CCRefs.Def && adjustCCMasksForInstr(MI, Compare, CCUsers))) {
EliminatedComparisons += 1;
return true;
@@ -441,7 +451,7 @@ bool SystemZElimCompare::optimizeCompareZero(
MachineInstr &MI = *MBBI;
if (preservesValueOf(MI, SrcReg)) {
// Try to eliminate Compare by reusing a CC result from MI.
- if (convertToLoadAndTest(MI)) {
+ if (convertToLoadAndTest(MI, Compare, CCUsers)) {
EliminatedComparisons += 1;
return true;
}
OpenPOWER on IntegriCloud