diff options
| author | Geoff Berry <gberry@codeaurora.org> | 2016-11-29 18:28:32 +0000 |
|---|---|---|
| committer | Geoff Berry <gberry@codeaurora.org> | 2016-11-29 18:28:32 +0000 |
| commit | 7c078fc035098853a7622f902d9ff80b1281d213 (patch) | |
| tree | 96e70ae48b17fc9caa92d4538a28316e8f1a19a7 /llvm/lib | |
| parent | 86150471c6c3f5e0f41fafb838b02cd0e1388a46 (diff) | |
| download | bcm5719-llvm-7c078fc035098853a7622f902d9ff80b1281d213.tar.gz bcm5719-llvm-7c078fc035098853a7622f902d9ff80b1281d213.zip | |
[AArch64] Fold spills of COPY of WZR/XZR
Summary:
In AArch64InstrInfo::foldMemoryOperandImpl, catch more cases where the
COPY being spilled is copying from WZR/XZR, but the source register is
not in the COPY destination register's regclass.
For example, when spilling:
%vreg0 = COPY %XZR ; %vreg0:GPR64common
without this change, the code in TargetInstrInfo::foldMemoryOperand()
and canFoldCopy() that normally handles cases like this would fail to
optimize since %XZR is not in GPR64common. So the spill code generated
would be:
%vreg0 = COPY %XZR
STR %vreg
instead of the new code generated:
STR %XZR
Reviewers: qcolombet, MatzeB
Subscribers: mcrosier, aemerson, t.p.northover, llvm-commits, rengolin
Differential Revision: https://reviews.llvm.org/D26976
llvm-svn: 288176
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 465137f2750..7a3f39df659 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2598,6 +2598,31 @@ MachineInstr *AArch64InstrInfo::foldMemoryOperandImpl( } } + // Handle the case where a WZR/XZR copy is being spilled but the destination + // register class doesn't contain WZR/XZR. For example: + // + // %vreg0<def> = COPY %XZR; GPR64common:%vreg0 + // + // In this case we can still safely fold away the COPY and generate the + // following spill code: + // + // STRXui %XZR, <fi#0> + // + if (MI.isFullCopy() && Ops.size() == 1 && Ops[0] == 0) { + MachineBasicBlock &MBB = *MI.getParent(); + const MachineOperand &SrcMO = MI.getOperand(1); + unsigned SrcReg = SrcMO.getReg(); + if (SrcReg == AArch64::WZR || SrcReg == AArch64::XZR) { + const TargetRegisterInfo &TRI = getRegisterInfo(); + const TargetRegisterClass &RC = SrcReg == AArch64::WZR + ? AArch64::GPR32RegClass + : AArch64::GPR64RegClass; + storeRegToStackSlot(MBB, InsertPt, SrcReg, SrcMO.isKill(), FrameIndex, + &RC, &TRI); + return &*--InsertPt; + } + } + // Cannot fold. return nullptr; } |

