diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp
index 8826df4..c51aaf1 100644
--- a/lib/CodeGen/RegisterCoalescer.cpp
+++ b/lib/CodeGen/RegisterCoalescer.cpp
@@ -1186,6 +1186,50 @@ static unsigned ComputeUltimateVN(VNInfo *VNI,
   return ThisValNoAssignments[VN] = UltimateVN;
 }
 
+static bool foobar(CoalescerPair &CP, const MachineInstr *MI,
+                   LiveRange *lr) {
+  unsigned Src, Dst, SrcSub, DstSub;
+  if (!CP.isMoveInstr(MI, Src, Dst, SrcSub, DstSub))
+    return false;
+
+  if (!MI->isCopy() || SrcSub || DstSub ||
+      !TargetRegisterInfo::isVirtualRegister(Src) ||
+      !TargetRegisterInfo::isVirtualRegister(Dst))
+    return false;
+
+  unsigned A = CP.getDstReg();
+  unsigned B = CP.getSrcReg();
+
+  if (!TargetRegisterInfo::isVirtualRegister(A) ||
+      !TargetRegisterInfo::isVirtualRegister(B))
+    return false;
+
+  if (B == Dst)
+    std::swap(A, B);
+  assert(Dst == A);
+
+  VNInfo *Other = lr->valno;
+  if (!Other->isDefByCopy())
+    return false;
+  const MachineInstr *OtherMI = Other->getCopy();
+
+  unsigned OtherSrc, OtherDst, OtherSrcSub, OtherDstSub;
+  if (!CP.isMoveInstr(OtherMI, OtherSrc, OtherDst, OtherSrcSub,
+                      OtherDstSub))
+    return false;
+
+  if (!OtherMI->isCopy() || OtherSrcSub || OtherDstSub ||
+      !TargetRegisterInfo::isVirtualRegister(OtherSrc) ||
+      !TargetRegisterInfo::isVirtualRegister(OtherDst))
+    return false;
+
+  assert(OtherDst == B);
+
+  if (Src != OtherSrc)
+    return false;
+  return true;
+}
+
 /// JoinIntervals - Attempt to join these two intervals.  On failure, this
 /// returns false.
 bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) {
@@ -1256,15 +1300,17 @@ bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) {
     if (VNI->hasRedefByEC())
       return false;
 
-    // DstReg is known to be a register in the LHS interval.  If the src is
-    // from the RHS interval, we can use its value #.
-    if (!CP.isCoalescable(VNI->getCopy()))
-      continue;
-
     // Figure out the value # from the RHS.
     LiveRange *lr = RHS.getLiveRangeContaining(VNI->def.getPrevSlot());
     // The copy could be to an aliased physreg.
     if (!lr) continue;
+
+    // DstReg is known to be a register in the LHS interval.  If the src is
+    // from the RHS interval, we can use its value #.
+    const MachineInstr *MI = VNI->getCopy();
+    if (!CP.isCoalescable(MI) && !foobar(CP, MI, lr))
+      continue;
+
     LHSValsDefinedFromRHS[VNI] = lr->valno;
   }
 
@@ -1280,15 +1326,17 @@ bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) {
     if (VNI->hasRedefByEC())
       return false;
 
-    // DstReg is known to be a register in the RHS interval.  If the src is
-    // from the LHS interval, we can use its value #.
-    if (!CP.isCoalescable(VNI->getCopy()))
-      continue;
-
     // Figure out the value # from the LHS.
     LiveRange *lr = LHS.getLiveRangeContaining(VNI->def.getPrevSlot());
     // The copy could be to an aliased physreg.
     if (!lr) continue;
+
+    // DstReg is known to be a register in the RHS interval.  If the src is
+    // from the LHS interval, we can use its value #.
+    const MachineInstr *MI = VNI->getCopy();
+    if (!CP.isCoalescable(MI) && !foobar(CP, MI, lr))
+        continue;
+
     RHSValsDefinedFromLHS[VNI] = lr->valno;
   }
 
diff --git a/lib/CodeGen/RegisterCoalescer.h b/lib/CodeGen/RegisterCoalescer.h
index 2e8a8ae..a503245 100644
--- a/lib/CodeGen/RegisterCoalescer.h
+++ b/lib/CodeGen/RegisterCoalescer.h
@@ -284,15 +284,15 @@ namespace llvm {
     /// compose - Compose subreg indices a and b, either may be 0.
     unsigned compose(unsigned, unsigned) const;
 
-    /// isMoveInstr - Return true if MI is a move or subreg instruction.
-    bool isMoveInstr(const MachineInstr *MI, unsigned &Src, unsigned &Dst,
-                     unsigned &SrcSub, unsigned &DstSub) const;
-
   public:
     CoalescerPair(const TargetInstrInfo &tii, const TargetRegisterInfo &tri)
       : tii_(tii), tri_(tri), dstReg_(0), srcReg_(0), subIdx_(0),
         partial_(false), crossClass_(false), flipped_(false), newRC_(0) {}
 
+    /// isMoveInstr - Return true if MI is a move or subreg instruction.
+    bool isMoveInstr(const MachineInstr *MI, unsigned &Src, unsigned &Dst,
+                     unsigned &SrcSub, unsigned &DstSub) const;
+
     /// setRegisters - set registers to match the copy instruction MI. Return
     /// false if MI is not a coalescable copy instruction.
     bool setRegisters(const MachineInstr*);
