[AVX-512] Teach X86InstrInfo::copyPhysReg to use a 512-bit move if XMM16-XMM31 or...
authorCraig Topper <craig.topper@gmail.com>
Tue, 20 Sep 2016 06:49:17 +0000 (06:49 +0000)
committerCraig Topper <craig.topper@gmail.com>
Tue, 20 Sep 2016 06:49:17 +0000 (06:49 +0000)
This can happen with SUBREG_TO_REG of ZMM16-ZMM31. Fixes PR30430.

llvm-svn: 281959

llvm/lib/Target/X86/X86InstrInfo.cpp
llvm/lib/Target/X86/X86RegisterInfo.cpp
llvm/lib/Target/X86/X86RegisterInfo.h

index b40004f..3035ddc 100644 (file)
@@ -4704,11 +4704,31 @@ void X86InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
   }
   else if (X86::VR64RegClass.contains(DestReg, SrcReg))
     Opc = X86::MMX_MOVQ64rr;
-  else if (X86::VR128XRegClass.contains(DestReg, SrcReg))
-    Opc = HasVLX ? X86::VMOVAPSZ128rr : HasAVX ? X86::VMOVAPSrr : X86::MOVAPSrr;
-  else if (X86::VR256XRegClass.contains(DestReg, SrcReg))
-    Opc = HasVLX ? X86::VMOVAPSZ256rr : X86::VMOVAPSYrr;
-  else if (X86::VR512RegClass.contains(DestReg, SrcReg))
+  else if (X86::VR128XRegClass.contains(DestReg, SrcReg)) {
+    if (HasVLX)
+      Opc = X86::VMOVAPSZ128rr;
+    else if (X86::VR128RegClass.contains(DestReg, SrcReg))
+      Opc = HasAVX ? X86::VMOVAPSrr : X86::MOVAPSrr;
+    else {
+      // If this an extended register and we don't have VLX we need to use a
+      // 512-bit move.
+      Opc = X86::VMOVAPSZrr;
+      DestReg = get512BitSuperRegister(DestReg);
+      SrcReg = get512BitSuperRegister(SrcReg);
+    }
+  } else if (X86::VR256XRegClass.contains(DestReg, SrcReg)) {
+    if (HasVLX)
+      Opc = X86::VMOVAPSZ256rr;
+    else if (X86::VR256RegClass.contains(DestReg, SrcReg))
+      Opc = X86::VMOVAPSYrr;
+    else {
+      // If this an extended register and we don't have VLX we need to use a
+      // 512-bit move.
+      Opc = X86::VMOVAPSZrr;
+      DestReg = get512BitSuperRegister(DestReg);
+      SrcReg = get512BitSuperRegister(SrcReg);
+    }
+  } else if (X86::VR512RegClass.contains(DestReg, SrcReg))
     Opc = X86::VMOVAPSZrr;
   // All KMASK RegClasses hold the same k registers, can be tested against anyone.
   else if (X86::VK16RegClass.contains(DestReg, SrcReg))
index 1b2fece..6324bd4 100644 (file)
@@ -691,3 +691,13 @@ X86RegisterInfo::getPtrSizedFrameRegister(const MachineFunction &MF) const {
     FrameReg = getX86SubSuperRegister(FrameReg, 32);
   return FrameReg;
 }
+
+unsigned llvm::get512BitSuperRegister(unsigned Reg) {
+  if (Reg >= X86::XMM0 && Reg <= X86::XMM31)
+    return X86::ZMM0 + (Reg - X86::XMM0);
+  if (Reg >= X86::YMM0 && Reg <= X86::YMM31)
+    return X86::ZMM0 + (Reg - X86::YMM0);
+  if (Reg >= X86::ZMM0 && Reg <= X86::ZMM31)
+    return Reg;
+  llvm_unreachable("Unexpected SIMD register");
+}
index 468012b..8d0094c 100644 (file)
@@ -137,6 +137,9 @@ public:
   unsigned getSlotSize() const { return SlotSize; }
 };
 
+//get512BitRegister - X86 utility - returns 512-bit super register
+unsigned get512BitSuperRegister(unsigned Reg);
+
 } // End llvm namespace
 
 #endif