Index: lib/Target/X86/X86ATTAsmPrinter.cpp
===================================================================
--- lib/Target/X86/X86ATTAsmPrinter.cpp	(revision 40578)
+++ lib/Target/X86/X86ATTAsmPrinter.cpp	(working copy)
@@ -576,15 +576,6 @@
 ///
 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   ++EmittedInsts;
-
-  // See if a truncate instruction can be turned into a nop.
-  switch (MI->getOpcode()) {
-  default: break;
-  case X86::PsMOVZX64rr32:
-    O << TAI->getCommentString() << " ZERO-EXTEND " << "\n\t";
-    break;
-  }
-
   // Call the autogenerated instruction printer routines.
   printInstruction(MI);
 }
Index: lib/Target/X86/X86RegisterInfo.cpp
===================================================================
--- lib/Target/X86/X86RegisterInfo.cpp	(revision 40578)
+++ lib/Target/X86/X86RegisterInfo.cpp	(working copy)
@@ -700,7 +700,8 @@
       { X86::PSHUFDri,        X86::PSHUFDmi },
       { X86::PSHUFHWri,       X86::PSHUFHWmi },
       { X86::PSHUFLWri,       X86::PSHUFLWmi },
-      { X86::PsMOVZX64rr32,   X86::PsMOVZX64rm32 },
+      // This became an INSERT_SUBREG(in, 3) so folding will be more complex
+      // { X86::PsMOVZX64rr32,   X86::PsMOVZX64rm32 }, 
       { X86::TEST16rr,        X86::TEST16rm },
       { X86::TEST32rr,        X86::TEST32rm },
       { X86::TEST64rr,        X86::TEST64rm },
Index: lib/Target/X86/X86InstrX86-64.td
===================================================================
--- lib/Target/X86/X86InstrX86-64.td	(revision 40578)
+++ lib/Target/X86/X86InstrX86-64.td	(working copy)
@@ -1007,9 +1007,6 @@
 
 // Zero-extension
 // TODO: Remove this after proper i32 -> i64 zext support.
-def PsMOVZX64rr32: I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR32:$src),
-                     "mov{l} {$src, ${dst:subreg32}|${dst:subreg32}, $src}",
-                     [(set GR64:$dst, (zext GR32:$src))]>;
 def PsMOVZX64rm32: I<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
                      "mov{l} {$src, ${dst:subreg32}|${dst:subreg32}, $src}",
                      [(set GR64:$dst, (zextloadi64i32 addr:$src))]>;
@@ -1086,7 +1083,7 @@
 // anyext -> zext
 def : Pat<(i64 (anyext GR8 :$src)), (MOVZX64rr8  GR8 :$src)>;
 def : Pat<(i64 (anyext GR16:$src)), (MOVZX64rr16 GR16:$src)>;
-def : Pat<(i64 (anyext GR32:$src)), (PsMOVZX64rr32 GR32:$src)>;
+// (i64 (anyext GR32:$src)) handled in C++ isel code
 def : Pat<(i64 (anyext (loadi8  addr:$src))), (MOVZX64rm8  addr:$src)>;
 def : Pat<(i64 (anyext (loadi16 addr:$src))), (MOVZX64rm16 addr:$src)>;
 def : Pat<(i64 (anyext (loadi32 addr:$src))), (PsMOVZX64rm32 addr:$src)>;
Index: lib/Target/X86/X86ISelDAGToDAG.cpp
===================================================================
--- lib/Target/X86/X86ISelDAGToDAG.cpp	(revision 40578)
+++ lib/Target/X86/X86ISelDAGToDAG.cpp	(working copy)
@@ -1258,6 +1258,18 @@
 
       return NULL;
     }
+
+    case ISD::ANY_EXTEND:
+    case ISD::ZERO_EXTEND:
+      if (NVT == MVT::i64) {
+        if (Node->getOperand(0).getValueType() == MVT::i32) {
+          // Use 2 operand insert
+          SDOperand Tmp = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
+          return CurDAG->getTargetNode(X86::INSERT_SUBREG, NVT, 
+                                       Node->getOperand(0), Tmp);
+        }
+      }
+      break;
       
     case ISD::TRUNCATE: {
       SDOperand Tmp;
Index: lib/Target/X86/X86IntelAsmPrinter.cpp
===================================================================
--- lib/Target/X86/X86IntelAsmPrinter.cpp	(revision 40578)
+++ lib/Target/X86/X86IntelAsmPrinter.cpp	(working copy)
@@ -302,15 +302,6 @@
 ///
 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   ++EmittedInsts;
-
-  // See if a truncate instruction can be turned into a nop.
-  switch (MI->getOpcode()) {
-  default: break;
-  case X86::PsMOVZX64rr32:
-    O << TAI->getCommentString() << " ZERO-EXTEND " << "\n\t";
-    break;
-  }
-
   // Call the autogenerated instruction printer routines.
   printInstruction(MI);
 }
