Skip to content

Commit cdb6072

Browse files
burgholzerCopilotpre-commit-ci[bot]
authored
✨ Add native support for R(theta, phi) gate (#1283)
## Description This PR adds native support for the $R(\theta, \phi)$ parametrized single-qubit gate. This is the native single-qubit gate for IQM quantum computers. In Qiskit, it is available as https://quantum.cloud.ibm.com/docs/en/api/qiskit/qiskit.circuit.library.RGate This PR adds the corresponding support to: - the Core IR - the OpenQASM parser - the DD Package - the ZX Package - the QIR runtime - the Qiskit plugin - the MLIR dialects and conversions ## Checklist: <!--- This checklist serves as a reminder of a couple of things that ensure your pull request will be merged swiftly. --> - [x] The pull request only contains commits that are focused and relevant to this change. - [x] I have added appropriate tests that cover the new/changed functionality. - [x] I have updated the documentation to reflect these changes. - [x] I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals. - [x] I have added migration instructions to the upgrade guide (if needed). - [x] The changes follow the project's style guidelines and introduce no new warnings. - [x] The changes are fully tested and pass the CI checks. - [x] I have reviewed my own code changes. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Native support for the R(theta, phi) single-qubit rotation gate with controlled and multi-controlled variants, usable with numeric or symbolic parameters and integrated across MLIR/QIR, runtime, and Python/Qiskit interfaces. * **Tests** * Added unit and integration tests and updated conversion and dialect tests to cover the new R gate and its phased variant. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: burgholzer <burgholzer@me.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: burgholzer <6358767+burgholzer@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent a29f012 commit cdb6072

41 files changed

Lines changed: 497 additions & 148 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel
1111

1212
### Added
1313

14+
- ✨ Add native support for `R(theta, phi)` gate ([#1283]) ([**@burgholzer**])
1415
- ✨ Add A\*-search-based routing algorithm to MLIR transpilation routines ([#1237], [#1271], [#1279]) ([**@MatthiasReumann**])
1516

1617
### Fixed
@@ -220,6 +221,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool
220221

221222
<!-- PR links -->
222223

224+
[#1283]: https://github.com/munich-quantum-toolkit/core/pull/1283
223225
[#1279]: https://github.com/munich-quantum-toolkit/core/pull/1279
224226
[#1276]: https://github.com/munich-quantum-toolkit/core/pull/1276
225227
[#1271]: https://github.com/munich-quantum-toolkit/core/pull/1271

bindings/ir/operations/register_optype.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ void registerOptype(const py::module& m) {
4848
.value("rx", qc::OpType::RX)
4949
.value("ry", qc::OpType::RY)
5050
.value("rz", qc::OpType::RZ)
51+
.value("r", qc::OpType::R)
5152
.value("swap", qc::OpType::SWAP)
5253
.value("iswap", qc::OpType::iSWAP)
5354
.value("iswapdg", qc::OpType::iSWAPdg)

bindings/ir/register_quantum_computation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ void registerQuantumComputation(py::module& m) {
345345
py::arg(#param1), "controls"_a, "target"_a);
346346

347347
DEFINE_SINGLE_TARGET_TWO_PARAMETER_OPERATION(u2, phi, lambda_)
348+
DEFINE_SINGLE_TARGET_TWO_PARAMETER_OPERATION(r, theta, phi)
348349

349350
#define DEFINE_SINGLE_TARGET_THREE_PARAMETER_OPERATION(op, param0, param1, \
350351
param2) \

include/mqt-core/ir/QuantumComputation.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ class QuantumComputation {
252252
const Controls& controls, const Qubit target);
253253

254254
DECLARE_SINGLE_TARGET_TWO_PARAMETER_OPERATION(u2, phi, lambda)
255+
DECLARE_SINGLE_TARGET_TWO_PARAMETER_OPERATION(r, theta, phi)
255256

256257
#undef DECLARE_SINGLE_TARGET_TWO_PARAMETER_OPERATION
257258

include/mqt-core/ir/operations/OpType.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <istream>
1515
#include <ostream>
1616
#include <string>
17+
#include <string_view>
1718

1819
namespace qc {
1920

@@ -90,6 +91,7 @@ std::string shortName(OpType opType);
9091
case RX:
9192
case RY:
9293
case RZ:
94+
case R:
9395
return true;
9496
default:
9597
return false;
@@ -100,7 +102,7 @@ inline std::ostream& operator<<(std::ostream& out, const OpType opType) {
100102
return out << toString(opType);
101103
}
102104

103-
[[nodiscard]] OpType opTypeFromString(const std::string& opType);
105+
[[nodiscard]] OpType opTypeFromString(std::string_view opType);
104106

105107
inline std::istream& operator>>(std::istream& in, OpType& opType) {
106108
std::string opTypeStr;

include/mqt-core/ir/operations/OpType.inc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ HANDLE_OP_TYPE(14, SXdg, OpTypeInv, "sxdg")
3232
HANDLE_OP_TYPE(15, RX, OpTypeNone, "rx")
3333
HANDLE_OP_TYPE(16, RY, OpTypeNone, "ry")
3434
HANDLE_OP_TYPE(17, RZ, OpTypeDiag, "rz")
35+
HANDLE_OP_TYPE(41, R, OpTypeNone, "r")
3536
HANDLE_OP_TYPE(18, SWAP, OpTypeNone, "swap")
36-
HANDLE_OP_TYPE(19, iSWAP, OpTypeNone, "iswap")
37+
HANDLE_OP_TYPE(19, iSWAP, OpTypeNone, "iswap")
3738
HANDLE_OP_TYPE(19, iSWAPdg, OpTypeInv, "iswapdg")
3839
HANDLE_OP_TYPE(20, Peres, OpTypeNone, "peres")
3940
HANDLE_OP_TYPE(20, Peresdg, OpTypeInv, "peresdg")
@@ -68,7 +69,7 @@ HANDLE_OP_TYPE(38, AodActivate, 0, "aod_activate")
6869
HANDLE_OP_TYPE(39, AodDeactivate, 0, "aod_deactivate")
6970
HANDLE_OP_TYPE(40, AodMove, 0, "aod_move")
7071

71-
LAST_OP_TYPE(41)
72+
LAST_OP_TYPE(42)
7273

7374

7475
#undef OpTypeInv

include/mqt-core/qasm3/StdGates.hpp

Lines changed: 169 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -49,75 +49,184 @@ const std::string QE1LIB = "gate rccx a, b, c {\n"
4949
const std::map<std::string, std::shared_ptr<Gate>> STANDARD_GATES = {
5050
// gates from which all other gates can be constructed.
5151
{"gphase",
52-
std::make_shared<StandardGate>(StandardGate({0, 0, 1, qc::GPhase}))},
53-
{"U", std::make_shared<StandardGate>(StandardGate({0, 1, 3, qc::U}))},
52+
std::make_shared<StandardGate>(StandardGate({.nControls = 0,
53+
.nTargets = 0,
54+
.nParameters = 1,
55+
.type = qc::GPhase}))},
56+
{"U",
57+
std::make_shared<StandardGate>(StandardGate(
58+
{.nControls = 0, .nTargets = 1, .nParameters = 3, .type = qc::U}))},
5459

5560
// natively supported gates
56-
{"p", std::make_shared<StandardGate>(StandardGate({0, 1, 1, qc::P}))},
57-
{"u1", std::make_shared<StandardGate>(StandardGate({0, 1, 1, qc::P}))},
58-
{"phase", std::make_shared<StandardGate>(StandardGate({0, 1, 1, qc::P}))},
59-
{"cphase", std::make_shared<StandardGate>(StandardGate({1, 1, 1, qc::P}))},
60-
{"cp", std::make_shared<StandardGate>(StandardGate({1, 1, 1, qc::P}))},
61-
62-
{"id", std::make_shared<StandardGate>(StandardGate({0, 1, 0, qc::I}))},
63-
{"u2", std::make_shared<StandardGate>(StandardGate({0, 1, 2, qc::U2}))},
64-
{"u3", std::make_shared<StandardGate>(StandardGate({0, 1, 3, qc::U}))},
65-
{"u", std::make_shared<StandardGate>(StandardGate({0, 1, 3, qc::U}))},
66-
67-
{"x", std::make_shared<StandardGate>(StandardGate({0, 1, 0, qc::X}))},
68-
{"cx", std::make_shared<StandardGate>(StandardGate({1, 1, 0, qc::X}))},
69-
{"CX", std::make_shared<StandardGate>(StandardGate({1, 1, 0, qc::X}))},
70-
{"ccx", std::make_shared<StandardGate>(StandardGate({2, 1, 0, qc::X}))},
71-
{"c3x", std::make_shared<StandardGate>(StandardGate({3, 1, 0, qc::X}))},
72-
{"c4x", std::make_shared<StandardGate>(StandardGate({4, 1, 0, qc::X}))},
73-
74-
{"rx", std::make_shared<StandardGate>(StandardGate({0, 1, 1, qc::RX}))},
75-
{"crx", std::make_shared<StandardGate>(StandardGate({1, 1, 1, qc::RX}))},
76-
77-
{"y", std::make_shared<StandardGate>(StandardGate({0, 1, 0, qc::Y}))},
78-
{"cy", std::make_shared<StandardGate>(StandardGate({1, 1, 0, qc::Y}))},
79-
80-
{"ry", std::make_shared<StandardGate>(StandardGate({0, 1, 1, qc::RY}))},
81-
{"cry", std::make_shared<StandardGate>(StandardGate({1, 1, 1, qc::RY}))},
82-
83-
{"z", std::make_shared<StandardGate>(StandardGate({0, 1, 0, qc::Z}))},
84-
{"cz", std::make_shared<StandardGate>(StandardGate({1, 1, 0, qc::Z}))},
85-
86-
{"rz", std::make_shared<StandardGate>(StandardGate({0, 1, 1, qc::RZ}))},
87-
{"crz", std::make_shared<StandardGate>(StandardGate({1, 1, 1, qc::RZ}))},
88-
89-
{"h", std::make_shared<StandardGate>(StandardGate({0, 1, 0, qc::H}))},
90-
{"ch", std::make_shared<StandardGate>(StandardGate({1, 1, 0, qc::H}))},
91-
92-
{"s", std::make_shared<StandardGate>(StandardGate({0, 1, 0, qc::S}))},
93-
{"sdg", std::make_shared<StandardGate>(StandardGate({0, 1, 0, qc::Sdg}))},
94-
95-
{"t", std::make_shared<StandardGate>(StandardGate({0, 1, 0, qc::T}))},
96-
{"tdg", std::make_shared<StandardGate>(StandardGate({0, 1, 0, qc::Tdg}))},
97-
98-
{"sx", std::make_shared<StandardGate>(StandardGate({0, 1, 0, qc::SX}))},
99-
{"sxdg", std::make_shared<StandardGate>(StandardGate({0, 1, 0, qc::SXdg}))},
61+
{"p",
62+
std::make_shared<StandardGate>(StandardGate(
63+
{.nControls = 0, .nTargets = 1, .nParameters = 1, .type = qc::P}))},
64+
{"u1",
65+
std::make_shared<StandardGate>(StandardGate(
66+
{.nControls = 0, .nTargets = 1, .nParameters = 1, .type = qc::P}))},
67+
{"phase",
68+
std::make_shared<StandardGate>(StandardGate(
69+
{.nControls = 0, .nTargets = 1, .nParameters = 1, .type = qc::P}))},
70+
{"cphase",
71+
std::make_shared<StandardGate>(StandardGate(
72+
{.nControls = 1, .nTargets = 1, .nParameters = 1, .type = qc::P}))},
73+
{"cp",
74+
std::make_shared<StandardGate>(StandardGate(
75+
{.nControls = 1, .nTargets = 1, .nParameters = 1, .type = qc::P}))},
76+
77+
{"id",
78+
std::make_shared<StandardGate>(StandardGate(
79+
{.nControls = 0, .nTargets = 1, .nParameters = 0, .type = qc::I}))},
80+
{"u2",
81+
std::make_shared<StandardGate>(StandardGate(
82+
{.nControls = 0, .nTargets = 1, .nParameters = 2, .type = qc::U2}))},
83+
{"u3",
84+
std::make_shared<StandardGate>(StandardGate(
85+
{.nControls = 0, .nTargets = 1, .nParameters = 3, .type = qc::U}))},
86+
{"u",
87+
std::make_shared<StandardGate>(StandardGate(
88+
{.nControls = 0, .nTargets = 1, .nParameters = 3, .type = qc::U}))},
89+
90+
{"x",
91+
std::make_shared<StandardGate>(StandardGate(
92+
{.nControls = 0, .nTargets = 1, .nParameters = 0, .type = qc::X}))},
93+
{"cx",
94+
std::make_shared<StandardGate>(StandardGate(
95+
{.nControls = 1, .nTargets = 1, .nParameters = 0, .type = qc::X}))},
96+
{"CX",
97+
std::make_shared<StandardGate>(StandardGate(
98+
{.nControls = 1, .nTargets = 1, .nParameters = 0, .type = qc::X}))},
99+
{"ccx",
100+
std::make_shared<StandardGate>(StandardGate(
101+
{.nControls = 2, .nTargets = 1, .nParameters = 0, .type = qc::X}))},
102+
{"c3x",
103+
std::make_shared<StandardGate>(StandardGate(
104+
{.nControls = 3, .nTargets = 1, .nParameters = 0, .type = qc::X}))},
105+
{"c4x",
106+
std::make_shared<StandardGate>(StandardGate(
107+
{.nControls = 4, .nTargets = 1, .nParameters = 0, .type = qc::X}))},
108+
109+
{"rx",
110+
std::make_shared<StandardGate>(StandardGate(
111+
{.nControls = 0, .nTargets = 1, .nParameters = 1, .type = qc::RX}))},
112+
{"crx",
113+
std::make_shared<StandardGate>(StandardGate(
114+
{.nControls = 1, .nTargets = 1, .nParameters = 1, .type = qc::RX}))},
115+
116+
{"y",
117+
std::make_shared<StandardGate>(StandardGate(
118+
{.nControls = 0, .nTargets = 1, .nParameters = 0, .type = qc::Y}))},
119+
{"cy",
120+
std::make_shared<StandardGate>(StandardGate(
121+
{.nControls = 1, .nTargets = 1, .nParameters = 0, .type = qc::Y}))},
122+
123+
{"ry",
124+
std::make_shared<StandardGate>(StandardGate(
125+
{.nControls = 0, .nTargets = 1, .nParameters = 1, .type = qc::RY}))},
126+
{"cry",
127+
std::make_shared<StandardGate>(StandardGate(
128+
{.nControls = 1, .nTargets = 1, .nParameters = 1, .type = qc::RY}))},
129+
130+
{"z",
131+
std::make_shared<StandardGate>(StandardGate(
132+
{.nControls = 0, .nTargets = 1, .nParameters = 0, .type = qc::Z}))},
133+
{"cz",
134+
std::make_shared<StandardGate>(StandardGate(
135+
{.nControls = 1, .nTargets = 1, .nParameters = 0, .type = qc::Z}))},
136+
137+
{"rz",
138+
std::make_shared<StandardGate>(StandardGate(
139+
{.nControls = 0, .nTargets = 1, .nParameters = 1, .type = qc::RZ}))},
140+
{"crz",
141+
std::make_shared<StandardGate>(StandardGate(
142+
{.nControls = 1, .nTargets = 1, .nParameters = 1, .type = qc::RZ}))},
143+
144+
{"r",
145+
std::make_shared<StandardGate>(StandardGate(
146+
{.nControls = 0, .nTargets = 1, .nParameters = 2, .type = qc::R}))},
147+
{"prx",
148+
std::make_shared<StandardGate>(StandardGate(
149+
{.nControls = 0, .nTargets = 1, .nParameters = 2, .type = qc::R}))},
150+
{"cr",
151+
std::make_shared<StandardGate>(StandardGate(
152+
{.nControls = 1, .nTargets = 1, .nParameters = 2, .type = qc::R}))},
153+
154+
{"h",
155+
std::make_shared<StandardGate>(StandardGate(
156+
{.nControls = 0, .nTargets = 1, .nParameters = 0, .type = qc::H}))},
157+
{"ch",
158+
std::make_shared<StandardGate>(StandardGate(
159+
{.nControls = 1, .nTargets = 1, .nParameters = 0, .type = qc::H}))},
160+
161+
{"s",
162+
std::make_shared<StandardGate>(StandardGate(
163+
{.nControls = 0, .nTargets = 1, .nParameters = 0, .type = qc::S}))},
164+
{"sdg",
165+
std::make_shared<StandardGate>(StandardGate(
166+
{.nControls = 0, .nTargets = 1, .nParameters = 0, .type = qc::Sdg}))},
167+
168+
{"t",
169+
std::make_shared<StandardGate>(StandardGate(
170+
{.nControls = 0, .nTargets = 1, .nParameters = 0, .type = qc::T}))},
171+
{"tdg",
172+
std::make_shared<StandardGate>(StandardGate(
173+
{.nControls = 0, .nTargets = 1, .nParameters = 0, .type = qc::Tdg}))},
174+
175+
{"sx",
176+
std::make_shared<StandardGate>(StandardGate(
177+
{.nControls = 0, .nTargets = 1, .nParameters = 0, .type = qc::SX}))},
178+
{"sxdg",
179+
std::make_shared<StandardGate>(StandardGate(
180+
{.nControls = 0, .nTargets = 1, .nParameters = 0, .type = qc::SXdg}))},
100181
{"c3sqrtx",
101-
std::make_shared<StandardGate>(StandardGate({3, 1, 0, qc::SXdg}))},
182+
std::make_shared<StandardGate>(StandardGate(
183+
{.nControls = 3, .nTargets = 1, .nParameters = 0, .type = qc::SXdg}))},
102184

103-
{"swap", std::make_shared<StandardGate>(StandardGate({0, 2, 0, qc::SWAP}))},
185+
{"swap",
186+
std::make_shared<StandardGate>(StandardGate(
187+
{.nControls = 0, .nTargets = 2, .nParameters = 0, .type = qc::SWAP}))},
104188
{"cswap",
105-
std::make_shared<StandardGate>(StandardGate({1, 2, 0, qc::SWAP}))},
189+
std::make_shared<StandardGate>(StandardGate(
190+
{.nControls = 1, .nTargets = 2, .nParameters = 0, .type = qc::SWAP}))},
106191

107192
{"iswap",
108-
std::make_shared<StandardGate>(StandardGate({0, 2, 0, qc::iSWAP}))},
193+
std::make_shared<StandardGate>(StandardGate({.nControls = 0,
194+
.nTargets = 2,
195+
.nParameters = 0,
196+
.type = qc::iSWAP}))},
109197
{"iswapdg",
110-
std::make_shared<StandardGate>(StandardGate({0, 2, 0, qc::iSWAPdg}))},
111-
112-
{"rxx", std::make_shared<StandardGate>(StandardGate({0, 2, 1, qc::RXX}))},
113-
{"ryy", std::make_shared<StandardGate>(StandardGate({0, 2, 1, qc::RYY}))},
114-
{"rzz", std::make_shared<StandardGate>(StandardGate({0, 2, 1, qc::RZZ}))},
115-
{"rzx", std::make_shared<StandardGate>(StandardGate({0, 2, 1, qc::RZX}))},
116-
{"dcx", std::make_shared<StandardGate>(StandardGate({0, 2, 0, qc::DCX}))},
117-
{"ecr", std::make_shared<StandardGate>(StandardGate({0, 2, 0, qc::ECR}))},
198+
std::make_shared<StandardGate>(StandardGate({.nControls = 0,
199+
.nTargets = 2,
200+
.nParameters = 0,
201+
.type = qc::iSWAPdg}))},
202+
203+
{"rxx",
204+
std::make_shared<StandardGate>(StandardGate(
205+
{.nControls = 0, .nTargets = 2, .nParameters = 1, .type = qc::RXX}))},
206+
{"ryy",
207+
std::make_shared<StandardGate>(StandardGate(
208+
{.nControls = 0, .nTargets = 2, .nParameters = 1, .type = qc::RYY}))},
209+
{"rzz",
210+
std::make_shared<StandardGate>(StandardGate(
211+
{.nControls = 0, .nTargets = 2, .nParameters = 1, .type = qc::RZZ}))},
212+
{"rzx",
213+
std::make_shared<StandardGate>(StandardGate(
214+
{.nControls = 0, .nTargets = 2, .nParameters = 1, .type = qc::RZX}))},
215+
{"dcx",
216+
std::make_shared<StandardGate>(StandardGate(
217+
{.nControls = 0, .nTargets = 2, .nParameters = 0, .type = qc::DCX}))},
218+
{"ecr",
219+
std::make_shared<StandardGate>(StandardGate(
220+
{.nControls = 0, .nTargets = 2, .nParameters = 0, .type = qc::ECR}))},
118221
{"xx_minus_yy",
119-
std::make_shared<StandardGate>(StandardGate({0, 2, 2, qc::XXminusYY}))},
222+
std::make_shared<StandardGate>(StandardGate({.nControls = 0,
223+
.nTargets = 2,
224+
.nParameters = 2,
225+
.type = qc::XXminusYY}))},
120226
{"xx_plus_yy",
121-
std::make_shared<StandardGate>(StandardGate({0, 2, 2, qc::XXplusYY}))},
227+
std::make_shared<StandardGate>(StandardGate({.nControls = 0,
228+
.nTargets = 2,
229+
.nParameters = 2,
230+
.type = qc::XXplusYY}))},
122231
};
123232
} // namespace qasm3

include/mqt-core/qir/runtime/QIR.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ void __quantum__qis__sqrtx__body(Qubit*);
116116
void __quantum__qis__sqrtxdg__body(Qubit*);
117117
void __quantum__qis__t__body(Qubit*);
118118
void __quantum__qis__tdg__body(Qubit*);
119+
void __quantum__qis__r__body(Qubit*, double, double);
120+
void __quantum__qis__prx__body(Qubit*, double, double);
119121
void __quantum__qis__rx__body(Qubit*, double);
120122
void __quantum__qis__ry__body(Qubit*, double);
121123
void __quantum__qis__rz__body(Qubit*, double);

mlir/include/mlir/Dialect/Common/IR/StdOps.td.inc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,16 @@ def SXdgOp : UnitaryOp<"sxdg", [OneTarget, NoParameter]> {
178178
}];
179179
}
180180

181+
def ROp : UnitaryOp<"r", [OneTarget, TwoParameters]> {
182+
let summary = "R operation";
183+
184+
let description = [{
185+
This class represents a R gate. It takes a qubit and a variadic
186+
list of positive/negative controls as an input. Additionally, it accepts
187+
two parameters indicating the degree of the rotation angles.
188+
}];
189+
}
190+
181191
def RXOp : UnitaryOp<"rx", [OneTarget, OneParameter]> {
182192
let summary = "RX operation";
183193

mlir/lib/Conversion/MQTOptToMQTRef/MQTOptToMQTRef.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ struct MQTOptToMQTRef final : impl::MQTOptToMQTRefBase<MQTOptToMQTRef> {
322322
ADD_CONVERT_PATTERN(POp)
323323
ADD_CONVERT_PATTERN(SXOp)
324324
ADD_CONVERT_PATTERN(SXdgOp)
325+
ADD_CONVERT_PATTERN(ROp)
325326
ADD_CONVERT_PATTERN(RXOp)
326327
ADD_CONVERT_PATTERN(RYOp)
327328
ADD_CONVERT_PATTERN(RZOp)

0 commit comments

Comments
 (0)