diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp | 16 | ||||
-rw-r--r-- | lib/Target/ARM64/ARM64InstrInfo.td | 16 |
2 files changed, 24 insertions, 8 deletions
diff --git a/lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp b/lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp index 5d2afae3fff..7d2a97f8e72 100644 --- a/lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp +++ b/lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp @@ -28,7 +28,7 @@ namespace { class ARM64DeadRegisterDefinitions : public MachineFunctionPass { private: const TargetRegisterInfo *TRI; - bool implicitlyDefinesSubReg(unsigned Reg, const MachineInstr &MI); + bool implicitlyDefinesOverlappingReg(unsigned Reg, const MachineInstr &MI); bool processMachineBasicBlock(MachineBasicBlock &MBB); bool usesFrameIndex(const MachineInstr &MI); public: @@ -47,12 +47,11 @@ public: char ARM64DeadRegisterDefinitions::ID = 0; } // end anonymous namespace -bool -ARM64DeadRegisterDefinitions::implicitlyDefinesSubReg(unsigned Reg, - const MachineInstr &MI) { +bool ARM64DeadRegisterDefinitions::implicitlyDefinesOverlappingReg( + unsigned Reg, const MachineInstr &MI) { for (const MachineOperand &MO : MI.implicit_operands()) if (MO.isReg() && MO.isDef()) - if (TRI->isSubRegister(Reg, MO.getReg())) + if (TRI->regsOverlap(Reg, MO.getReg())) return true; return false; } @@ -86,9 +85,10 @@ ARM64DeadRegisterDefinitions::processMachineBasicBlock(MachineBasicBlock &MBB) { DEBUG(dbgs() << " Ignoring, def is tied operand.\n"); continue; } - // Don't change the register if there's an implicit def of a subreg. - if (implicitlyDefinesSubReg(MO.getReg(), MI)) { - DEBUG(dbgs() << " Ignoring, implicitly defines subregister.\n"); + // Don't change the register if there's an implicit def of a subreg or + // supperreg. + if (implicitlyDefinesOverlappingReg(MO.getReg(), MI)) { + DEBUG(dbgs() << " Ignoring, implicitly defines overlap reg.\n"); continue; } // Make sure the instruction take a register class that contains diff --git a/lib/Target/ARM64/ARM64InstrInfo.td b/lib/Target/ARM64/ARM64InstrInfo.td index 9f599eb2355..69f1e2c5a6d 100644 --- a/lib/Target/ARM64/ARM64InstrInfo.td +++ b/lib/Target/ARM64/ARM64InstrInfo.td @@ -395,6 +395,22 @@ def MOVi64imm Sched<[WriteImm]>; } // isReMaterializable, isCodeGenOnly +// If possible, we want to use MOVi32imm even for 64-bit moves. This gives the +// eventual expansion code fewer bits to worry about getting right. Marshalling +// the types is a little tricky though: +def i64imm_32bit : ImmLeaf<i64, [{ + return (Imm & 0xffffffffULL) == Imm; +}]>; + +def trunc_imm : SDNodeXForm<imm, [{ + return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i32); +}]>; + +def : Pat<(i64 i64imm_32bit:$src), + (SUBREG_TO_REG (i64 0), (MOVi32imm (trunc_imm imm:$src)), sub_32)>; + +// Deal with the various forms of (ELF) large addressing with MOVZ/MOVK +// sequences. def : Pat<(ARM64WrapperLarge tglobaladdr:$g3, tglobaladdr:$g2, tglobaladdr:$g1, tglobaladdr:$g0), (MOVKXi (MOVKXi (MOVKXi (MOVZXi tglobaladdr:$g3, 48), |