diff options
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp b/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp index a935d39ccfd..f3c8e7e9bdc 100644 --- a/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp +++ b/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp @@ -154,30 +154,37 @@ AArch64RedundantCopyElimination::knownRegValInBlock( // Track clobbered registers. trackRegDefs(PredI, ClobberedRegs, TRI); + bool IsCMN = false; switch (PredI.getOpcode()) { default: break; + // CMN is an alias for ADDS with a dead destination register. + case AArch64::ADDSWri: + case AArch64::ADDSXri: + IsCMN = true; // CMP is an alias for SUBS with a dead destination register. case AArch64::SUBSWri: case AArch64::SUBSXri: { - unsigned SrcReg = PredI.getOperand(1).getReg(); + MCPhysReg SrcReg = PredI.getOperand(1).getReg(); + // Must not be a symbolic immediate. if (!PredI.getOperand(2).isImm()) return None; - // FIXME: For simplicity, give up on non-zero shifts. - if (PredI.getOperand(3).getImm()) - return None; - // The src register must not be modified between the cmp and conditional // branch. This includes a self-clobbering compare. if (ClobberedRegs[SrcReg]) return None; // We've found the Cmp that sets NZCV. + int32_t KnownImm = PredI.getOperand(2).getImm(); + int32_t Shift = PredI.getOperand(3).getImm(); + KnownImm <<= Shift; + if (IsCMN) + KnownImm = -KnownImm; FirstUse = PredI; - return RegImm(PredI.getOperand(1).getReg(), PredI.getOperand(2).getImm()); + return RegImm(SrcReg, KnownImm); } } |

