summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorGeoff Berry <gberry@codeaurora.org>2016-11-29 18:28:32 +0000
committerGeoff Berry <gberry@codeaurora.org>2016-11-29 18:28:32 +0000
commit7c078fc035098853a7622f902d9ff80b1281d213 (patch)
tree96e70ae48b17fc9caa92d4538a28316e8f1a19a7 /llvm/lib
parent86150471c6c3f5e0f41fafb838b02cd0e1388a46 (diff)
downloadbcm5719-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.cpp25
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;
}
OpenPOWER on IntegriCloud