Repository: Qiskit/qiskit

Issue:
Left over U1 gates at optimization level 2
<!-- ⚠️ 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
- **Python version**:
- **Operating system**:

### What is the current behavior?
```python

import numpy as np
from qiskit import *

qc = QuantumCircuit(3)
qc.h(0)
qc.h(1)
qc.cp(np.pi/8,0,1)

qc.cp(np.pi/4,0,2)
trans_qc = transpile(qc, basis_gates=['id', 'rz', 'sx', 'x', 'cx'], optimization_level=2)
trans_qc.draw()
```

gives

```
global phase: -26.4090132442392
     ┌─────────┐┌────┐┌────────────┐                                         »
q_0: ┤ RZ(π/2) ├┤ √X ├┤ U1(11π/16) ├──■──────────────────■────────────────■──»
     ├─────────┤├────┤└┬─────────┬─┘┌─┴─┐┌────────────┐┌─┴─┐┌──────────┐  │  »
q_1: ┤ RZ(π/2) ├┤ √X ├─┤ RZ(π/2) ├──┤ X ├┤ RZ(6.0868) ├┤ X ├┤ RZ(π/16) ├──┼──»
     └─────────┘└────┘ └─────────┘  └───┘└────────────┘└───┘└──────────┘┌─┴─┐»
q_2: ───────────────────────────────────────────────────────────────────┤ X ├»
                                                                        └───┘»
«                                  
«q_0: ───────────────■─────────────
«                    │             
«q_1: ───────────────┼─────────────
«     ┌───────────┐┌─┴─┐┌─────────┐
«q_2: ┤ RZ(15π/8) ├┤ X ├┤ RZ(π/8) ├
«     └───────────┘└───┘└─────────┘
```


### Steps to reproduce the problem



### What is the expected behavior?



### Suggested solutions





Discussion:
I looked into this when I saw #5665 filed earlier this morning:

https://github.com/Qiskit/qiskit-terra/issues/5665#issuecomment-764616777

> So I took a quick look to dig into this issue this morning. The issue is the `CommutativeCancellation` transpiler pass isn't basis gate aware and only knows how to use the U1 gates for z rotations: https://github.com/Qiskit/qiskit-terra/blob/master/qiskit/transpiler/passes/optimization/commutative_cancellation.py
> 
> To fix this we probably either need to update the pass to basis aware, or update the default level2 pass manager to run basis translation in the fixed point loop after we run commutative cancellation.

Resolving patch:
diff --git a/qiskit/transpiler/preset_passmanagers/level2.py b/qiskit/transpiler/preset_passmanagers/level2.py
--- a/qiskit/transpiler/preset_passmanagers/level2.py
+++ b/qiskit/transpiler/preset_passmanagers/level2.py
@@ -206,7 +206,7 @@ def _opt_control(property_set):
         pm2.append(_direction_check)
         pm2.append(_direction, condition=_direction_condition)
     pm2.append(_reset)
-    pm2.append(_depth_check + _opt, do_while=_opt_control)
+    pm2.append(_depth_check + _opt + _unroll, do_while=_opt_control)
     if scheduling_method:
         pm2.append(_scheduling)
 


Test patch:
diff --git a/test/python/transpiler/test_preset_passmanagers.py b/test/python/transpiler/test_preset_passmanagers.py
--- a/test/python/transpiler/test_preset_passmanagers.py
+++ b/test/python/transpiler/test_preset_passmanagers.py
@@ -14,6 +14,8 @@
 from test import combine
 from ddt import ddt, data
 
+import numpy as np
+
 from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
 from qiskit.circuit import Qubit
 from qiskit.compiler import transpile, assemble
@@ -85,6 +87,23 @@ def test_level0_keeps_reset(self):
         result = transpile(circuit, basis_gates=None, optimization_level=0)
         self.assertEqual(result, circuit)
 
+    def test_level2_respects_basis(self):
+        """Test that level2 with commutative cancellation respects basis"""
+        qc = QuantumCircuit(3)
+        qc.h(0)
+        qc.h(1)
+        qc.cp(np.pi / 8, 0, 1)
+        qc.cp(np.pi / 4, 0, 2)
+        result = transpile(qc, basis_gates=['id', 'rz', 'sx', 'x', 'cx'],
+                           optimization_level=2)
+
+        dag = circuit_to_dag(result)
+        op_nodes = [node.name for node in dag.topological_op_nodes()]
+        # Assert no u1 or rx gates from commutative cancellation end up in
+        # end up in the output since they're not in the target basis gates
+        self.assertNotIn('u1', op_nodes)
+        self.assertNotIn('rx', op_nodes)
+
 
 @ddt
 class TestTranspileLevels(QiskitTestCase):