eliminate MOV64r0 in favor of a Pat<> pattern. This is only nontrivial because
authorChris Lattner <sabre@nondot.org>
Sun, 12 Jul 2009 00:47:55 +0000 (00:47 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 12 Jul 2009 00:47:55 +0000 (00:47 +0000)
the div lowering code explicitly references it.

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

lib/Target/X86/X86ISelDAGToDAG.cpp
lib/Target/X86/X86Instr64bit.td
lib/Target/X86/X86InstrInfo.cpp

index 8aa627f8a7abecebc5206d6f685fb3da6da6e89e..0c23ba8cef730da300ca608be4131db273c72139 100644 (file)
@@ -1604,7 +1604,7 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
         break;
       case MVT::i64:
         LoReg = X86::RAX; HiReg = X86::RDX;
-        ClrOpcode  = X86::MOV64r0;
+        ClrOpcode  = ~0U; // NOT USED.
         SExtOpcode = X86::CQO;
         break;
       }
@@ -1643,8 +1643,26 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
             SDValue(CurDAG->getTargetNode(SExtOpcode, dl, MVT::Flag, InFlag),0);
         } else {
           // Zero out the high part, effectively zero extending the input.
-          SDValue ClrNode = SDValue(CurDAG->getTargetNode(ClrOpcode, dl, NVT), 
-                                    0);
+          SDValue ClrNode;
+          
+          if (NVT.getSimpleVT() == MVT::i64) {
+            ClrNode = SDValue(CurDAG->getTargetNode(X86::MOV32r0, dl, MVT::i32),
+                              0);
+            // We just did a 32-bit clear, insert it into a 64-bit register to
+            // clear the whole 64-bit reg.
+            SDValue Undef =
+              SDValue(CurDAG->getTargetNode(TargetInstrInfo::IMPLICIT_DEF,
+                                            dl, MVT::i64), 0);
+            SDValue SubRegNo = 
+              CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32);
+            ClrNode = 
+              SDValue(CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG, dl,
+                                            MVT::i64, Undef, ClrNode, SubRegNo),
+                      0);
+          } else {
+            ClrNode = SDValue(CurDAG->getTargetNode(ClrOpcode, dl, NVT), 0);
+          }
+          
           InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, HiReg,
                                         ClrNode, InFlag).getValue(1);
         }
index ba886e45acae3d6f6122c679073240971bed59a8..dd6f984144f397d5066c0881077e6ea3229b43ea 100644 (file)
@@ -1305,14 +1305,12 @@ def Int_CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src)
 // Alias instructions that map movr0 to xor. Use xorl instead of xorq; it's
 // equivalent due to implicit zero-extending, and it sometimes has a smaller
 // encoding.
-// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
-// FIXME: AddedComplexity gives MOV64r0 a higher priority than MOV64ri32. Remove
+// FIXME: AddedComplexity gives this a higher priority than MOV64ri32. Remove
 // when we have a better way to specify isel priority.
-let Defs = [EFLAGS], AddedComplexity = 1,
-    isReMaterializable = 1, isAsCheapAsAMove = 1 in
-def MOV64r0  : I<0x31, MRMInitReg,  (outs GR64:$dst), (ins),
-                "xor{l}\t${dst:subreg32}, ${dst:subreg32}",
-                [(set GR64:$dst, 0)]>;
+let AddedComplexity = 1 in
+def : Pat<(i64 0),
+          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32r0), x86_subreg_32bit)>;
+
 
 // Materialize i64 constant where top 32-bits are zero.
 let AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in
index 572b71dbc01da538b759c26ba131dd5489691bfe..514e80dbf65eed5d36a2a6e06adb8025820c25d5 100644 (file)
@@ -929,8 +929,7 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
   default: break;
   case X86::MOV8r0:
   case X86::MOV16r0:
-  case X86::MOV32r0:
-  case X86::MOV64r0: {
+  case X86::MOV32r0: {
     if (!isSafeToClobberEFLAGS(MBB, I)) {
       unsigned Opc = 0;
       switch (Orig->getOpcode()) {
@@ -938,7 +937,6 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
       case X86::MOV8r0:  Opc = X86::MOV8ri;  break;
       case X86::MOV16r0: Opc = X86::MOV16ri; break;
       case X86::MOV32r0: Opc = X86::MOV32ri; break;
-      case X86::MOV64r0: Opc = X86::MOV64ri32; break;
       }
       BuildMI(MBB, I, DL, get(Opc), DestReg).addImm(0);
       Emitted = true;
@@ -2165,8 +2163,6 @@ X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
       NewMI = MakeM0Inst(*this, X86::MOV16mi, MOs, MI);
     else if (MI->getOpcode() == X86::MOV32r0)
       NewMI = MakeM0Inst(*this, X86::MOV32mi, MOs, MI);
-    else if (MI->getOpcode() == X86::MOV64r0)
-      NewMI = MakeM0Inst(*this, X86::MOV64mi32, MOs, MI);
     else if (MI->getOpcode() == X86::MOV8r0)
       NewMI = MakeM0Inst(*this, X86::MOV8mi, MOs, MI);
     if (NewMI)
@@ -2365,10 +2361,9 @@ bool X86InstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
     OpcodeTablePtr = &RegOp2MemOpTable2Addr;
   } else if (OpNum == 0) { // If operand 0
     switch (Opc) {
+    case X86::MOV8r0:
     case X86::MOV16r0:
     case X86::MOV32r0:
-    case X86::MOV64r0:
-    case X86::MOV8r0:
       return true;
     default: break;
     }