Repository: Qiskit/qiskit

Issue:
OptimizeSwapBeforeMeasure removes classically conditioned SwapGate
<!-- ⚠️ 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**:
- **Python version**:
- **Operating system**:

### What is the current behavior?

From https://travis-ci.com/github/Qiskit/qiskit-terra/jobs/495770351#L997:

```
>>> qc = qk.QuantumCircuit.from_qasm_str('''
OPENQASM 2.0;
include "qelib1.inc";
qreg q3134[2];
creg c137[1];
cx q3134[1],q3134[0];
h q3134[1];
if(c137==1) swap q3134[1],q3134[0];
measure q3134[1] -> c137[0];
''')
>>> qc.draw()
         ┌───┐               
q3134_0: ┤ X ├────────X──────
         └─┬─┘┌───┐   │   ┌─┐
q3134_1: ──■──┤ H ├───X───┤M├
              └───┘┌──╨──┐└╥┘
 c137: 1/══════════╡ = 1 ╞═╩═
                   └─────┘ 0 
>>> qk.transpile(qc, optimization_level=3).draw()
         ┌───┐     ┌─┐
q3134_0: ┤ X ├─────┤M├
         └─┬─┘┌───┐└╥┘
q3134_1: ──■──┤ H ├─╫─
              └───┘ ║ 
 c137: 1/═══════════╩═
                    0 
```

### Steps to reproduce the problem



### What is the expected behavior?



### Suggested solutions





Discussion:

Resolving patch:
diff --git a/qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py b/qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py
--- a/qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py
+++ b/qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py
@@ -37,10 +37,13 @@ def run(self, dag):
         """
         swaps = dag.op_nodes(SwapGate)
         for swap in swaps[::-1]:
+            if swap.op.condition is not None:
+                continue
             final_successor = []
             for successor in dag.successors(swap):
-                final_successor.append(successor.type == 'out' or (successor.type == 'op' and
-                                                                   successor.op.name == 'measure'))
+                final_successor.append(successor.type == 'out' or
+                                       (successor.type == 'op' and
+                                        isinstance(successor.op, Measure)))
             if all(final_successor):
                 # the node swap needs to be removed and, if a measure follows, needs to be adapted
                 swap_qargs = swap.qargs


Test patch:
diff --git a/test/python/transpiler/test_optimize_swap_before_measure.py b/test/python/transpiler/test_optimize_swap_before_measure.py
--- a/test/python/transpiler/test_optimize_swap_before_measure.py
+++ b/test/python/transpiler/test_optimize_swap_before_measure.py
@@ -218,6 +218,30 @@ def test_optimize_overlap_swap(self):
 
         self.assertEqual(expected, after)
 
+    def test_no_optimize_swap_with_condition(self):
+        """ Do not remove swap if it has a condition
+            qr0:--X--m--       qr0:--X--m--
+                  |  |               |  |
+            qr1:--X--|--  ==>  qr1:--X--|--
+                  |  |               |  |
+            cr0:--1--.--       cr0:--1--.--
+        """
+        qr = QuantumRegister(2, 'qr')
+        cr = ClassicalRegister(1, 'cr')
+        circuit = QuantumCircuit(qr, cr)
+        circuit.swap(qr[0], qr[1]).c_if(cr, 1)
+        circuit.measure(qr[0], cr[0])
+        dag = circuit_to_dag(circuit)
+
+        expected = QuantumCircuit(qr, cr)
+        expected.swap(qr[0], qr[1]).c_if(cr, 1)
+        expected.measure(qr[0], cr[0])
+
+        pass_ = OptimizeSwapBeforeMeasure()
+        after = pass_.run(dag)
+
+        self.assertEqual(circuit_to_dag(expected), after)
+
 
 if __name__ == '__main__':
     unittest.main()