summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/X86FrameLowering.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2018-02-07 21:41:50 +0000
committerCraig Topper <craig.topper@intel.com>2018-02-07 21:41:50 +0000
commit8baa9c77e3b2c063c8fa26627787730a610ce4f4 (patch)
tree64e93f36a8bb0becba811d9c757a3896f2f4e80e /llvm/lib/Target/X86/X86FrameLowering.cpp
parentfc940277cba00b3a023c8c0f15360df73319c2a4 (diff)
downloadbcm5719-llvm-8baa9c77e3b2c063c8fa26627787730a610ce4f4.tar.gz
bcm5719-llvm-8baa9c77e3b2c063c8fa26627787730a610ce4f4.zip
[X86] When doing callee save/restore for k-registers make sure we don't use KMOVQ on non-BWI targets
If we are saving/restoring k-registers, the default behavior of getMinimalRegisterClass will find the VK64 class with a spill size of 64 bits. This will cause the KMOVQ opcode to be used for save/restore. If we don't have have BWI instructions we need to constrain the class returned to give us VK16 with a 16-bit spill size. We can do this by passing the either v16i1 or v64i1 into getMinimalRegisterClass. Also add asserts to make sure BWI is enabled anytime we use KMOVD/KMOVQ. These are what caught this bug. Fixes PR36256 Differential Revision: https://reviews.llvm.org/D42989 llvm-svn: 324533
Diffstat (limited to 'llvm/lib/Target/X86/X86FrameLowering.cpp')
-rw-r--r--llvm/lib/Target/X86/X86FrameLowering.cpp22
1 files changed, 19 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 729bd17a71d..36f29b042b6 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -1925,7 +1925,12 @@ bool X86FrameLowering::assignCalleeSavedSpillSlots(
if (X86::GR64RegClass.contains(Reg) || X86::GR32RegClass.contains(Reg))
continue;
- const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+ // If this is k-register make sure we lookup via the largest legal type.
+ MVT VT = MVT::Other;
+ if (X86::VK16RegClass.contains(Reg))
+ VT = STI.hasBWI() ? MVT::v64i1 : MVT::v16i1;
+
+ const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, VT);
unsigned Size = TRI->getSpillSize(*RC);
unsigned Align = TRI->getSpillAlignment(*RC);
// ensure alignment
@@ -1992,9 +1997,15 @@ bool X86FrameLowering::spillCalleeSavedRegisters(
unsigned Reg = CSI[i-1].getReg();
if (X86::GR64RegClass.contains(Reg) || X86::GR32RegClass.contains(Reg))
continue;
+
+ // If this is k-register make sure we lookup via the largest legal type.
+ MVT VT = MVT::Other;
+ if (X86::VK16RegClass.contains(Reg))
+ VT = STI.hasBWI() ? MVT::v64i1 : MVT::v16i1;
+
// Add the callee-saved register as live-in. It's killed at the spill.
MBB.addLiveIn(Reg);
- const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+ const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, VT);
TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i - 1].getFrameIdx(), RC,
TRI);
@@ -2068,7 +2079,12 @@ bool X86FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
X86::GR32RegClass.contains(Reg))
continue;
- const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+ // If this is k-register make sure we lookup via the largest legal type.
+ MVT VT = MVT::Other;
+ if (X86::VK16RegClass.contains(Reg))
+ VT = STI.hasBWI() ? MVT::v64i1 : MVT::v16i1;
+
+ const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, VT);
TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI);
}
OpenPOWER on IntegriCloud