Constrain both operands on MOVZX32_NOREXrr8.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 7 Oct 2011 20:15:54 +0000 (20:15 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 7 Oct 2011 20:15:54 +0000 (20:15 +0000)
This instruction is explicitly encoded without an REX prefix, so both
operands but be *_NOREX.

Also add an assertion to copyPhysReg() that fires when the MOV8rr_NOREX
constraints are not satisfied.

This fixes a miscompilation in 20040709-2 in the gcc test suite.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141410 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86InstrExtension.td
lib/Target/X86/X86InstrInfo.cpp

index 2e1d523ea16dee7b1f4a26976e4fc8aaa4a9d49c..e62e6b701f463eefdf8a3fcf49657f2025a66c19 100644 (file)
@@ -76,12 +76,12 @@ def MOVZX32rm16: I<0xB7, MRMSrcMem, (outs GR32:$dst), (ins i16mem:$src),
 // except that they use GR32_NOREX for the output operand register class
 // instead of GR32. This allows them to operate on h registers on x86-64.
 def MOVZX32_NOREXrr8 : I<0xB6, MRMSrcReg,
-                         (outs GR32_NOREX:$dst), (ins GR8:$src),
+                         (outs GR32_NOREX:$dst), (ins GR8_NOREX:$src),
                          "movz{bl|x}\t{$src, $dst|$dst, $src}",
                          []>, TB;
 let mayLoad = 1 in
 def MOVZX32_NOREXrm8 : I<0xB6, MRMSrcMem,
-                         (outs GR32_NOREX:$dst), (ins i8mem:$src),
+                         (outs GR32_NOREX:$dst), (ins i8mem_NOREX:$src),
                          "movz{bl|x}\t{$src, $dst|$dst, $src}",
                          []>, TB;
 
index bad978d874711f07e3fd4957c905f936450161fb..86fb3a52724e932ad01c7b7f45ffc726a3813d60 100644 (file)
@@ -2189,9 +2189,12 @@ void X86InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     // Copying to or from a physical H register on x86-64 requires a NOREX
     // move.  Otherwise use a normal move.
     if ((isHReg(DestReg) || isHReg(SrcReg)) &&
-        TM.getSubtarget<X86Subtarget>().is64Bit())
+        TM.getSubtarget<X86Subtarget>().is64Bit()) {
       Opc = X86::MOV8rr_NOREX;
-    else
+      // Both operands must be encodable without an REX prefix.
+      assert(X86::GR8_NOREXRegClass.contains(SrcReg, DestReg) &&
+             "8-bit H register can not be copied outside GR8_NOREX");
+    } else
       Opc = X86::MOV8rr;
   } else if (X86::VR128RegClass.contains(DestReg, SrcReg))
     Opc = HasAVX ? X86::VMOVAPSrr : X86::MOVAPSrr;