Index: include/llvm/CodeGen/FastISel.h
===================================================================
--- include/llvm/CodeGen/FastISel.h
+++ include/llvm/CodeGen/FastISel.h
@@ -522,6 +522,7 @@
   bool selectCall(const User *Call);
   bool selectIntrinsicCall(const IntrinsicInst *II);
   bool selectBitCast(const User *I);
+  bool selectFreeze(const User *I);
   bool selectCast(const User *I, unsigned Opcode);
   bool selectExtractValue(const User *I);
   bool selectInsertValue(const User *I);
Index: include/llvm/CodeGen/ISDOpcodes.h
===================================================================
--- include/llvm/CodeGen/ISDOpcodes.h
+++ include/llvm/CodeGen/ISDOpcodes.h
@@ -177,6 +177,11 @@
     /// UNDEF - An undefined node.
     UNDEF,
 
+    // FREEZE - FREEZE(VAL) returns a random integer if VAL is UNDEF (or
+    // is evaluated to UNDEF), or returns VAL otherwise. Note that each
+    // read of UNDEF can yield different value, but FREEZE(UNDEF) cannot.
+    FREEZE,
+
     /// EXTRACT_ELEMENT - This is used to get the lower or upper (determined by
     /// a Constant, which is required to be operand #1) half of the integer or
     /// float value specified as operand #0.  This is only for use before
Index: include/llvm/CodeGen/SelectionDAGISel.h
===================================================================
--- include/llvm/CodeGen/SelectionDAGISel.h
+++ include/llvm/CodeGen/SelectionDAGISel.h
@@ -265,6 +265,8 @@
   void Select_UNDEF(SDNode *N);
   void CannotYetSelect(SDNode *N);
 
+  void Select_FREEZE(SDNode *N);
+
 private:
   void DoInstructionSelection();
   SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs,
Index: lib/CodeGen/SelectionDAG/FastISel.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/FastISel.cpp
+++ lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1316,6 +1316,28 @@
   return true;
 }
 
+bool FastISel::selectFreeze(const User *I) {
+  // Lower Freeze to reg-reg copy.
+  unsigned Reg = getRegForValue(I->getOperand(0));
+  if (!Reg)
+    // Unhandled operand.
+    return false;
+
+  EVT ETy = TLI.getValueType(DL, I->getOperand(0)->getType());
+  if (ETy == MVT::Other || !TLI.isTypeLegal(ETy))
+    // Unhandled type, bail out.
+    return false;
+
+  MVT Ty = ETy.getSimpleVT();
+  const TargetRegisterClass *TyRegClass = TLI.getRegClassFor(Ty);
+  unsigned ResultReg = createResultReg(TyRegClass);
+  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+          TII.get(TargetOpcode::COPY), ResultReg).addReg(Reg);
+
+  updateValueMap(I, ResultReg);
+  return true;
+}
+
 // Remove local value instructions starting from the instruction after
 // SavedLastLocalValue to the current function insert point.
 void FastISel::removeDeadLocalValueCode(MachineInstr *SavedLastLocalValue)
@@ -1645,6 +1667,9 @@
   case Instruction::ExtractValue:
     return selectExtractValue(I);
 
+  case Instruction::Freeze:
+    return selectFreeze(I);
+
   case Instruction::PHI:
     llvm_unreachable("FastISel shouldn't visit PHI nodes!");
 
Index: lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -154,6 +154,9 @@
   case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS:
     Res = PromoteIntRes_AtomicCmpSwap(cast<AtomicSDNode>(N), ResNo);
     break;
+  case ISD::FREEZE:
+    Res = PromoteIntRes_FREEZE(N);
+    break;
   }
 
   // If the result is null then the sub-method took care of registering it.
@@ -303,6 +306,12 @@
                      CreateStackStoreLoad(InOp, OutVT));
 }
 
+SDValue DAGTypeLegalizer::PromoteIntRes_FREEZE(SDNode *N) {
+  SDValue V = GetPromotedInteger(N->getOperand(0));
+  return DAG.getNode(N->getOpcode(), SDLoc(N),
+                     V.getValueType(), V);
+}
+
 SDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) {
   SDValue Op = GetPromotedInteger(N->getOperand(0));
   EVT OVT = N->getValueType(0);
@@ -904,6 +913,7 @@
   case ISD::SRL:
   case ISD::ROTL:
   case ISD::ROTR: Res = PromoteIntOp_Shift(N); break;
+  case ISD::FREEZE: Res = PromoteIntOp_FREEZE(N); break;
   }
 
   // If the result is null, the sub-method took care of registering results etc.
@@ -1252,6 +1262,10 @@
                                 N->getOperand(0).getValueType().getScalarType());
 }
 
+SDValue DAGTypeLegalizer::PromoteIntOp_FREEZE(SDNode *N) {
+  SDValue Op = GetPromotedInteger(N->getOperand(0));
+  return DAG.getNode(ISD::FREEZE, SDLoc(N), Op.getValueType(), Op);
+}
 
 //===----------------------------------------------------------------------===//
 //  Integer Result Expansion
@@ -1282,6 +1296,7 @@
   case ISD::SELECT:       SplitRes_SELECT(N, Lo, Hi); break;
   case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;
   case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
+  case ISD::FREEZE:       SplitRes_FREEZE(N, Lo, Hi); break;
 
   case ISD::BITCAST:            ExpandRes_BITCAST(N, Lo, Hi); break;
   case ISD::BUILD_PAIR:         ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
@@ -2747,6 +2762,7 @@
   case ISD::STORE:   Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break;
   case ISD::TRUNCATE:          Res = ExpandIntOp_TRUNCATE(N); break;
   case ISD::UINT_TO_FP:        Res = ExpandIntOp_UINT_TO_FP(N); break;
+  case ISD::FREEZE:            Res = ExpandIntOp_FREEZE(N); break;
 
   case ISD::SHL:
   case ISD::SRA:
@@ -3197,6 +3213,11 @@
   return Swap.getValue(1);
 }
 
+SDValue DAGTypeLegalizer::ExpandIntOp_FREEZE(SDNode *N) {
+  SDValue InL, InH;
+  GetExpandedInteger(N->getOperand(0), InL, InH);
+  return DAG.getNode(ISD::FREEZE, SDLoc(N), N->getValueType(0), InL);
+}
 
 SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N) {
   SDValue InOp0 = N->getOperand(0);
Index: lib/CodeGen/SelectionDAG/LegalizeTypes.h
===================================================================
--- lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -255,6 +255,7 @@
   SDValue PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N);
   SDValue PromoteIntRes_FP_TO_XINT(SDNode *N);
   SDValue PromoteIntRes_FP_TO_FP16(SDNode *N);
+  SDValue PromoteIntRes_FREEZE(SDNode *N);
   SDValue PromoteIntRes_INT_EXTEND(SDNode *N);
   SDValue PromoteIntRes_LOAD(LoadSDNode *N);
   SDValue PromoteIntRes_MLOAD(MaskedLoadSDNode *N);
@@ -290,6 +291,7 @@
   SDValue PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N, unsigned OpNo);
   SDValue PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N);
   SDValue PromoteIntOp_EXTRACT_SUBVECTOR(SDNode *N);
+  SDValue PromoteIntOp_FREEZE(SDNode *N);
   SDValue PromoteIntOp_CONCAT_VECTORS(SDNode *N);
   SDValue PromoteIntOp_SCALAR_TO_VECTOR(SDNode *N);
   SDValue PromoteIntOp_SELECT(SDNode *N, unsigned OpNo);
@@ -380,6 +382,7 @@
   SDValue ExpandIntOp_UINT_TO_FP(SDNode *N);
   SDValue ExpandIntOp_RETURNADDR(SDNode *N);
   SDValue ExpandIntOp_ATOMIC_STORE(SDNode *N);
+  SDValue ExpandIntOp_FREEZE(SDNode *N);
 
   void IntegerExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
                                   ISD::CondCode &CCCode, const SDLoc &dl);
@@ -809,6 +812,7 @@
   void SplitRes_SELECT      (SDNode *N, SDValue &Lo, SDValue &Hi);
   void SplitRes_SELECT_CC   (SDNode *N, SDValue &Lo, SDValue &Hi);
   void SplitRes_UNDEF       (SDNode *N, SDValue &Lo, SDValue &Hi);
+  void SplitRes_FREEZE      (SDNode *N, SDValue &Lo, SDValue &Hi);
 
   //===--------------------------------------------------------------------===//
   // Generic Expansion: LegalizeTypesGeneric.cpp
Index: lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
+++ lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
@@ -553,3 +553,12 @@
   Lo = DAG.getUNDEF(LoVT);
   Hi = DAG.getUNDEF(HiVT);
 }
+
+void DAGTypeLegalizer::SplitRes_FREEZE(SDNode *N, SDValue &Lo, SDValue &Hi) {
+  SDValue L, H;
+  SDLoc dl(N);
+  GetSplitOp(N->getOperand(0), L, H);
+
+  Lo = DAG.getNode(ISD::FREEZE, dl, L.getValueType(), L);
+  Hi = DAG.getNode(ISD::FREEZE, dl, H.getValueType(), H);
+}
Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -9350,5 +9350,9 @@
 
 void SelectionDAGBuilder::visitFreeze(const FreezeInst &I) {
   SDValue N = getValue(I.getOperand(0));
-  setValue(&I, N);
+  SDLoc dl = getCurSDLoc();
+  EVT DestVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
+                                                        I.getType());
+
+  setValue(&I, DAG.getNode(ISD::FREEZE, dl, DestVT, N));
 }
Index: lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -298,6 +298,7 @@
   case ISD::GC_TRANSITION_START:        return "gc_transition.start";
   case ISD::GC_TRANSITION_END:          return "gc_transition.end";
   case ISD::GET_DYNAMIC_AREA_OFFSET:    return "get.dynamic.area.offset";
+  case ISD::FREEZE:                     return "freeze";
 
   // Bit manipulation
   case ISD::BITREVERSE:                 return "bitreverse";
Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2227,6 +2227,57 @@
   CurDAG->SelectNodeTo(N, TargetOpcode::IMPLICIT_DEF, N->getValueType(0));
 }
 
+void SelectionDAGISel::Select_FREEZE(SDNode *N) {
+  SDValue Op = N->getOperand(0);
+  EVT Ty = N->getValueType(0);
+  SDLoc dl(N);
+
+  // Select FREEZE to CopyToReg + CopyFromReg.
+  // This blocks propagation of UNDEF while translating SelDag into
+  // MachineInstr.
+  // LLVM translates an UNDEF node into multiple IMPLICIT_DEF
+  // instructions (in MachineInstr) if the UNDEF has multiple uses.
+  // For example,
+  // 
+  // %y1 = UNDEF
+  // %t1 = mul i64 %y1, %y1
+  //
+  // It is translated into MachineInstr code
+  //
+  // %vreg2 = IMPLICIT_DEF
+  // %vreg3 = IMPLICIT_DEF
+  // %vreg1 = IMUL32rr %vreg2, %vreg3
+  //
+  // However, with freeze,
+  //
+  // %y1 = freeze i64 UNDEF
+  // %t1 = mul i64 %y1, %y1
+  //
+  // each read of %y1 must yield same value, so it must be translated into : 
+  // 
+  // %vreg2 = IMPLICIT_DEF
+  // %vreg1 = IMUL32rr %vreg2, %vreg2
+  //
+  // Selecting FREEZE into CopyToReg + CopyFromReg helps this.
+  //
+  // We don't have FREEZE pseudo-instruction in MachineInstr-level now.
+  // If FREEZE instruction is added later, the code below must be
+  // changed as well.
+
+  const TargetRegisterClass *RC = TLI->getRegClassFor(Ty.getSimpleVT());
+  // Create a new virtual register.
+  unsigned NewVirtReg = RegInfo->createVirtualRegister(RC);
+  // Create CopyToReg node ('copy val into NewVirtReg')
+  SDValue CTRVal = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
+                                        NewVirtReg, Op);
+  // Create CopyFromReg node ('get value from NewVirtReg')
+  SDValue CFRVal = CurDAG->getCopyFromReg(CTRVal, dl, NewVirtReg, Ty);
+  // Mark selected.
+  CTRVal->setNodeId(-1);
+  ReplaceUses(SDValue(N, 0), CFRVal);
+  CurDAG->RemoveDeadNode(N);
+}
+
 /// GetVBR - decode a vbr encoding whose top bit is set.
 LLVM_ATTRIBUTE_ALWAYS_INLINE static inline uint64_t
 GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) {
@@ -2853,6 +2904,9 @@
   case ISD::UNDEF:
     Select_UNDEF(NodeToMatch);
     return;
+  case ISD::FREEZE:
+    Select_FREEZE(NodeToMatch);
+    return;
   }
 
   assert(!NodeToMatch->isMachineOpcode() && "Node already selected!");
Index: lib/CodeGen/TargetLoweringBase.cpp
===================================================================
--- lib/CodeGen/TargetLoweringBase.cpp
+++ lib/CodeGen/TargetLoweringBase.cpp
@@ -1744,7 +1744,7 @@
   case ExtractValue:   return ISD::MERGE_VALUES;
   case InsertValue:    return ISD::MERGE_VALUES;
   case LandingPad:     return 0;
-  case Freeze:         return 0;
+  case Freeze:         return ISD::FREEZE;
   }
 
   llvm_unreachable("Unknown instruction type encountered!");
Index: test/CodeGen/X86/fast-isel-freeze.ll
===================================================================
--- /dev/null
+++ test/CodeGen/X86/fast-isel-freeze.ll
@@ -0,0 +1,15 @@
+; RUN: llc < %s                               -mtriple=x86_64-unknown-linux | FileCheck %s --check-prefix=SDAG
+; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-unknown-linux | FileCheck %s --check-prefix=FAST
+
+define i32 @freeze(i32 %t) {
+; SDAG:       movl  $10, %eax
+; SDAG-NEXT:  xorl  %edi, %eax
+; SDAG-NEXT:  retq
+; FAST:       movl  $10, %eax
+; FAST-NEXT:  xorl  %edi, %eax
+; FAST-NEXT:  retq
+  %1 = freeze i32 %t
+  %2 = freeze i32 10
+  %3 = xor i32 %1, %2
+  ret i32 %3
+}
Index: test/CodeGen/X86/fast-isel.ll
===================================================================
--- test/CodeGen/X86/fast-isel.ll
+++ test/CodeGen/X86/fast-isel.ll
@@ -99,6 +99,11 @@
   ret void
 }
 
+define void @freeze_i32(i1 %x) {
+  %t = freeze i1 %x
+  ret void
+}
+
 @crash_test1x = external global <2 x i32>, align 8
 
 define void @crash_test1() nounwind ssp {
Index: test/CodeGen/X86/freeze-legalize.ll
===================================================================
--- /dev/null
+++ test/CodeGen/X86/freeze-legalize.ll
@@ -0,0 +1,29 @@
+; Make sure that seldag legalization works correctly for freeze instruction.
+; RUN: llc -march=x86 < %s 2>&1 | FileCheck %s
+
+; CHECK: movl    $303174162, %ecx 
+; CHECK: movl    $875836468, %esi 
+; CHECK: movl    $1448498774, %edx
+; CHECK: movl    $2021161080, %eax
+; CHECK: xorl    %esi, %eax
+; CHECK: xorl    %ecx, %edx
+; CHECK: popl    %esi
+; CHECK: retl
+
+define i64 @expand(i32 %x) {
+  %y1 = freeze i64 1302123111658042420 ; 0x1212121234343434
+  %y2 = freeze i64 6221254864647256184 ; 0x5656565678787878
+  %t2 = xor i64 %y1, %y2
+  ret i64 %t2
+}
+
+; CHECK: movw    $682, %cx
+; CHECK: movw    $992, %ax
+; CHECK: addl    %ecx, %eax
+; CHECK: retl
+define i10 @promote() {
+  %a = freeze i10 682 ; 0x2AA
+  %b = freeze i10 992 ; 0x3E0
+  %res = add i10 %a, %b
+  ret i10 %res
+}
Index: test/CodeGen/X86/freeze.ll
===================================================================
--- /dev/null
+++ test/CodeGen/X86/freeze.ll
@@ -0,0 +1,19 @@
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu -print-machineinstrs=expand-isel-pseudos %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=MCINSTR
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s 2>&1 | FileCheck %s --check-prefix=X86ASM
+
+; X86ASM: imull   %eax, %eax
+; X86ASM: xorl    %eax, %eax
+; X86ASM: retq
+
+; MCINSTR: %vreg1[[attr1:.*]] = IMPLICIT_DEF;
+; MCINSTR: %vreg2[[attr2:.*]] = IMUL32rr %vreg1[[attr3:.*]], %vreg1,
+; MCINSTR: %vreg3[[attr4:.*]] = XOR32rr %vreg2[[attr5:.*]], %vreg1,
+; MCINSTR: %EAX[[attr6:.*]] = COPY %vreg3;
+; MCINSTR: RET 0, %EAX
+
+define i32 @foo(i32 %x) {
+  %y1 = freeze i32 undef
+  %t1 = mul i32 %y1, %y1
+  %t2 = xor i32 %t1, %y1
+  ret i32 %t2
+}