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.
@mtreinish I have a version which updates the pass to be basis aware. I thought this might avoid calling basis translation again.
My concern with that was it's still only going to work for a subset of basis out there. I don't think we can remove the basis translator and still handle any universal basis set. Like what if the basis is composed of completely custom gates?

I think we probably should do both approaches together, with https://github.com/ewinston/qiskit-terra/commit/90864c546454668b2575b7313c119c90813b20b9 commutative cancellation will use the basis if it knows about it, but if it doesn't it'll use a standard gate and rely on the basis translator to handle the conversion.
@mtreinish I think using both approaches sounds like a reasonable short term solution. If we don't guarantee transformation passes keep within a target basis then following up with translation would be necessary. Perhaps an intermediate solution (not in this issue) would for passes to indicate whether they respect target basis. Then applying the basis translator could be done only when needed.

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
@@ -201,7 +201,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):