Repository: Qiskit/qiskit

Issue:
Default optimization level does not perform self-inverse gate cancellations
<!-- ⚠️ 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**: latest
- **Python version**:
- **Operating system**:

### What is the current behavior?
```python

qc= QuantumCircuit(2)
qc.h(range(2))
qc.cz(0,1)
qc.draw()
```

```
     ┌───┐   
q_0: ┤ H ├─■─
     ├───┤ │ 
q_1: ┤ H ├─■─
     └───┘   
```

```python

transpile(qc, basis_gates=['h', 'cx']).draw()

```

```
     ┌───┐               
q_0: ┤ H ├───────■───────
     ├───┤┌───┐┌─┴─┐┌───┐
q_1: ┤ H ├┤ H ├┤ X ├┤ H ├
     └───┘└───┘└───┘└───┘
```


### Steps to reproduce the problem



### What is the expected behavior?
I would expect the default level of optimization to remove trivial things like repeated H gates.


### Suggested solutions





Discussion:
Work was recently started in this direction by @vadebayo49 (see #6855 and #6576 ) but there is still some work to be done before this can be utilized by the default optimization levels, namely a way to identify (either through gate annotations or a library) which gates and gate pairs are inverse.
This is caused by the `OneQubitEulerDecomposer` not knowing how to simplify things in terms of h (you can see a list of the basis it can work in here: https://qiskit.org/documentation/stubs/qiskit.quantum_info.OneQubitEulerDecomposer.html#qiskit.quantum_info.OneQubitEulerDecomposer). The level 1 optimization level doesn't contain any passes that know how to cancel two consecutive h gates. I think higher optimizations definitely will though.

I think we need to re-evaluate which passes we include in the different optimization levels because I think we can get away with more optimization in level 1 than we have right now.
It does work at level 2 and higher.  However, given that the vast majority of users just do `execute` at the default level, perhaps level 1 should be beefed up some as you suggest.

Resolving patch:
diff --git a/qiskit/transpiler/preset_passmanagers/builtin_plugins.py b/qiskit/transpiler/preset_passmanagers/builtin_plugins.py
--- a/qiskit/transpiler/preset_passmanagers/builtin_plugins.py
+++ b/qiskit/transpiler/preset_passmanagers/builtin_plugins.py
@@ -39,7 +39,7 @@
     CommutativeCancellation,
     Collect2qBlocks,
     ConsolidateBlocks,
-    CXCancellation,
+    InverseCancellation,
 )
 from qiskit.transpiler.passes import Depth, Size, FixedPoint, MinimumPoint
 from qiskit.transpiler.passes.utils.gates_basis import GatesInBasis
@@ -47,6 +47,23 @@
 from qiskit.passmanager.flow_controllers import ConditionalController
 from qiskit.transpiler.timing_constraints import TimingConstraints
 from qiskit.transpiler.passes.layout.vf2_layout import VF2LayoutStopReason
+from qiskit.circuit.library.standard_gates import (
+    CXGate,
+    ECRGate,
+    CZGate,
+    XGate,
+    YGate,
+    ZGate,
+    TGate,
+    TdgGate,
+    SwapGate,
+    SGate,
+    SdgGate,
+    HGate,
+    CYGate,
+    SXGate,
+    SXdgGate,
+)
 
 
 class DefaultInitPassManager(PassManagerStagePlugin):
@@ -468,7 +485,22 @@ def _opt_control(property_set):
                     Optimize1qGatesDecomposition(
                         basis=pass_manager_config.basis_gates, target=pass_manager_config.target
                     ),
-                    CXCancellation(),
+                    InverseCancellation(
+                        [
+                            CXGate(),
+                            ECRGate(),
+                            CZGate(),
+                            CYGate(),
+                            XGate(),
+                            YGate(),
+                            ZGate(),
+                            HGate(),
+                            SwapGate(),
+                            (TGate(), TdgGate()),
+                            (SGate(), SdgGate()),
+                            (SXGate(), SXdgGate()),
+                        ]
+                    ),
                 ]
             elif optimization_level == 2:
                 # Steps for optimization level 2


Test patch: