Repository: Qiskit/qiskit

Issue:
Transpiler routing incorrectly updates conditional gate value
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**: master @ b1c9a23
- **Python version**: 3.7
- **Operating system**: Linux

### What is the current behavior?

From https://travis-ci.com/github/Qiskit/qiskit-terra/jobs/375535972#L1673 :

```
Evaluating circuit at level 0 on fake_yorktown:

OPENQASM 2.0;
include "qelib1.inc";
qreg q2702[1];
qreg q2703[1];
qreg q2704[2];
creg c435[1];
creg c436[1];
h q2704[1];
if(c435==1) cx q2704[1],q2703[0];
h q2704[1];
measure q2704[1] -> c436[0];

AssertionError: Counts not equivalent: ('1 0': 0 != 2050), ('0 0': 4096 != 2046) within 204.8 delta
```

### Steps to reproduce the problem

Input circuit
```
                          
q0_0: ────────────────────
            ┌───┐         
q1_0: ──────┤ X ├─────────
            └─┬─┘         
q2_0: ────────┼───────────
      ┌───┐   │   ┌───┐┌─┐
q2_1: ┤ H ├───■───┤ H ├┤M├
      └───┘┌──┴──┐└───┘└╥┘
c0: 1/═════╡ = 1 ╞══════╬═
           └─────┘      ║ 
c1: 1/══════════════════╩═
                        0 
```

After transpile
```
                                           ┌───┐              ░    
     q1_0 -> 0 ────────────────────────────┤ X ├──────────────░────
                                           └─┬─┘              ░    
     q0_0 -> 1 ──────────────────────────────┼────────────────░────
                                ┌───┐        │   ┌──────────┐ ░ ┌─┐
     q2_0 -> 2 ──────────────■──┤ X ├──■─────■───┤ U2(0,pi) ├─░─┤M├
               ┌──────────┐┌─┴─┐└─┬─┘┌─┴─┐   │   └──────────┘ ░ └╥┘
     q2_1 -> 3 ┤ U2(0,pi) ├┤ X ├──■──┤ X ├───┼────────────────░──╫─
               └──────────┘└───┘     └───┘   │                ░  ║ 
ancilla_0 -> 4 ──────────────────────────────┼────────────────░──╫─
                                             │                ░  ║ 
         c0: 1/══════════════════════════════╪═══════════════════╬═
                                          ┌──┴──┐                ║ 
         c1: 1/═══════════════════════════╡ = 0 ╞════════════════╩═
                                          └─────┘                0 
```

Likely related to routing. If given an `initial_layout` that pre-routes the circuit, the conditional is preserved.

### What is the expected behavior?



### Suggested solutions





Discussion:

Resolving patch:
diff --git a/qiskit/dagcircuit/dagcircuit.py b/qiskit/dagcircuit/dagcircuit.py
--- a/qiskit/dagcircuit/dagcircuit.py
+++ b/qiskit/dagcircuit/dagcircuit.py
@@ -30,7 +30,7 @@
 import networkx as nx
 
 from qiskit.circuit.quantumregister import QuantumRegister, Qubit
-from qiskit.circuit.classicalregister import ClassicalRegister, Clbit
+from qiskit.circuit.classicalregister import ClassicalRegister
 from qiskit.circuit.gate import Gate
 from qiskit.dagcircuit.exceptions import DAGCircuitError
 from qiskit.dagcircuit.dagnode import DAGNode
@@ -480,19 +480,29 @@ def _map_condition(wire_map, condition):
         Returns:
             tuple(ClassicalRegister,int): new condition
         Raises:
-            DAGCircuitError: if condition register not in wire_map
+            DAGCircuitError: if condition register not in wire_map, or if
+                wire_map maps condition onto more than one creg
         """
+
         if condition is None:
             new_condition = None
         else:
             # if there is a condition, map the condition bits to the
             # composed cregs based on the wire_map
+            creg = condition[0]
             cond_val = condition[1]
             new_cond_val = 0
             new_creg = None
             for bit in wire_map:
-                if isinstance(bit, Clbit):
-                    new_creg = wire_map[bit].register
+                if bit in creg:
+                    if new_creg is None:
+                        new_creg = wire_map[bit].register
+                    elif new_creg != wire_map[bit].register:
+                        # Raise if wire_map maps condition creg on to more than one
+                        # creg in target DAG.
+                        raise DAGCircuitError('wire_map maps conditional '
+                                              'register onto more than one creg.')
+
                     if 2**(bit.index) & cond_val:
                         new_cond_val += 2**(wire_map[bit].index)
             if new_creg is None:


Test patch:
diff --git a/test/python/dagcircuit/test_compose.py b/test/python/dagcircuit/test_compose.py
--- a/test/python/dagcircuit/test_compose.py
+++ b/test/python/dagcircuit/test_compose.py
@@ -16,6 +16,7 @@
 
 from qiskit.circuit import QuantumRegister, ClassicalRegister, QuantumCircuit
 from qiskit.converters import circuit_to_dag, dag_to_circuit
+from qiskit.dagcircuit.exceptions import DAGCircuitError
 from qiskit.test import QiskitTestCase
 
 
@@ -379,6 +380,64 @@ def test_compose_classical(self):
 
         self.assertEqual(circuit_composed, circuit_expected)
 
+    def test_compose_condition_multiple_classical(self):
+        """Compose a circuit with more than one creg.
+
+                          ┌───┐              ┌───┐
+        q5_0:      q5_0: ─┤ H ├─      q5_0: ─┤ H ├─
+                          └─┬─┘              └─┬─┘
+                         ┌──┴──┐            ┌──┴──┐
+        c0:    +   c0: 1/╡ = 1 ╞   =  c0: 1/╡ = 1 ╞
+                         └─────┘            └─────┘
+        c1:        c1: 1/═══════      c1: 1/═══════
+        """
+        # ref: https://github.com/Qiskit/qiskit-terra/issues/4964
+
+        qreg = QuantumRegister(1)
+        creg1 = ClassicalRegister(1)
+        creg2 = ClassicalRegister(1)
+
+        circuit_left = QuantumCircuit(qreg, creg1, creg2)
+        circuit_right = QuantumCircuit(qreg, creg1, creg2)
+        circuit_right.h(0).c_if(creg1, 1)
+
+        dag_left = circuit_to_dag(circuit_left)
+        dag_right = circuit_to_dag(circuit_right)
+
+        dag_composed = dag_left.compose(dag_right,
+                                        qubits=[0],
+                                        clbits=[0, 1],
+                                        inplace=False)
+
+        dag_expected = circuit_to_dag(circuit_right.copy())
+
+        self.assertEqual(dag_composed, dag_expected)
+
+    def test_compose_raises_if_splitting_condition_creg(self):
+        """Verify compose raises if a condition is mapped to more than one creg.
+
+                             ┌───┐
+        q_0:           q_0: ─┤ H ├─
+                             └─┬─┘
+        c0: 1/  +           ┌──┴──┐   = DAGCircuitError
+                       c: 2/╡ = 2 ╞
+        c1: 1/              └─────┘
+        """
+
+        qreg = QuantumRegister(1)
+        creg1 = ClassicalRegister(1)
+        creg2 = ClassicalRegister(1)
+
+        circuit_left = QuantumCircuit(qreg, creg1, creg2)
+
+        wide_creg = ClassicalRegister(2)
+
+        circuit_right = QuantumCircuit(qreg, wide_creg)
+        circuit_right.h(0).c_if(wide_creg, 2)
+
+        with self.assertRaisesRegex(DAGCircuitError, 'more than one creg'):
+            circuit_left.compose(circuit_right)
+
 
 if __name__ == '__main__':
     unittest.main()