From b9d114f260bd579ebdf8abde6d56388f30d22c8c Mon Sep 17 00:00:00 2001 From: Li-ming Bao Date: Wed, 27 May 2026 13:06:49 +0200 Subject: [PATCH 1/8] refactor collectQuibitValuesInsideSCFOps to fix dangling reference --- mlir/lib/Conversion/QCToQCO/QCToQCO.cpp | 41 +++++++++++++++---------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/mlir/lib/Conversion/QCToQCO/QCToQCO.cpp b/mlir/lib/Conversion/QCToQCO/QCToQCO.cpp index 2e4833a565..08ef9f02d6 100644 --- a/mlir/lib/Conversion/QCToQCO/QCToQCO.cpp +++ b/mlir/lib/Conversion/QCToQCO/QCToQCO.cpp @@ -515,56 +515,63 @@ static void extractQubitsAfterOp(LoweringState& state, Operation* target, */ static std::pair, SetVector> collectQubitValuesInsideSCFOps(Operation* op, LoweringState* state) { - // Get the regions of the current operation - const auto& regions = op->getRegions(); - auto& regionQubitMap = state->regionQubitMap[op]; - auto& regionRegisterMap = state->regionRegisterMap[op]; + SetVector localQubits; + SetVector localRegisters; - for (auto& region : regions) { - auto& qubitInfoMap = state->qubitInfoMap[®ion]; + // Helper to check if a qubit value is defined locally + auto isDefinedLocally = [&](Region* region, Value value) { + auto it = state->qubitInfoMap.find(region); + return it != state->qubitInfoMap.end() && it->second.contains(value); + }; + + for (auto& region : op->getRegions()) { // Skip empty regions e.g. empty else region of an If operation if (region.empty()) { continue; } // Check that the region has only one block assert(region.hasOneBlock() && "Expected single-block region"); + // Iterate through all operations of the current region for (auto& operation : region.front().getOperations()) { // Recursively walk through nested regions if (operation.getNumRegions() > 0) { auto [qubits, registers] = collectQubitValuesInsideSCFOps(&operation, state); - regionQubitMap.set_union(qubits); - // Remove duplicate qubits - regionQubitMap.remove_if( - [&](Value qubit) { return qubitInfoMap.contains(qubit); }); - regionRegisterMap.set_union(registers); + for (Value qubit : qubits) { + if (!isDefinedLocally(®ion, qubit)) { + localQubits.insert(qubit); + } + } + localRegisters.set_union(registers); } // Track qubits from loadOp if (auto loadOp = dyn_cast(operation)) { QubitInfo info{.reg = loadOp.getMemRef(), .index = loadOp.getIndices()[0]}; - qubitInfoMap.try_emplace(loadOp.getResult(), info); - regionRegisterMap.insert(loadOp.getMemRef()); + state->qubitInfoMap[®ion].try_emplace(loadOp.getResult(), info); + localRegisters.insert(loadOp.getMemRef()); continue; } // Add the QC qubit and memref operands to the maps for (const auto& operand : operation.getOperands()) { if (isa(operand.getType())) { - if (!qubitInfoMap.contains(operand)) { - regionQubitMap.insert(operand); + if (!isDefinedLocally(®ion, operand)) { + localQubits.insert(operand); } } if (auto memref = dyn_cast(operand.getType())) { if (isa(memref.getElementType())) { - regionRegisterMap.insert(operand); + localRegisters.insert(operand); } } } } } + state->regionQubitMap[op].set_union(localQubits); + state->regionRegisterMap[op].set_union(localRegisters); - return {regionQubitMap, regionRegisterMap}; + return {state->regionQubitMap[op], state->regionRegisterMap[op]}; } namespace { From 65a763dad7dccf32566101c1bbd60c5072de04dd Mon Sep 17 00:00:00 2001 From: Li-ming Bao Date: Wed, 27 May 2026 13:37:32 +0200 Subject: [PATCH 2/8] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c3b5c34c8..5edd1b6c68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel - ✨ Add conversions between `jeff` and QCO ([#1479], [#1548], [#1565], [#1637], [#1676], [#1706]) ([**@denialhaag**], [**@burgholzer**]) - ✨ Add a `place-and-route` pass for mapping circuits to architectures with restricted topologies ([#1537], [#1547], [#1568], [#1581], [#1583], [#1588], [#1600], [#1664], [#1709], [#1716]) ([**@MatthiasReumann**], [**@burgholzer**]) - ✨ Add initial infrastructure for new QC and QCO MLIR dialects - ([#1264], [#1330], [#1402], [#1428], [#1430], [#1436], [#1443], [#1446], [#1464], [#1465], [#1470], [#1471], [#1472], [#1474], [#1475], [#1506], [#1510], [#1513], [#1521], [#1542], [#1548], [#1550], [#1554], [#1567], [#1569], [#1570], [#1572], [#1573], [#1580], [#1602], [#1620], [#1623], [#1624], [#1626], [#1627], [#1635], [#1638], [#1673], [#1675], [#1700], [#1717], [#1730]) + ([#1264], [#1330], [#1402], [#1428], [#1430], [#1436], [#1443], [#1446], [#1464], [#1465], [#1470], [#1471], [#1472], [#1474], [#1475], [#1506], [#1510], [#1513], [#1521], [#1542], [#1548], [#1550], [#1554], [#1567], [#1569], [#1570], [#1572], [#1573], [#1580], [#1602], [#1620], [#1623], [#1624], [#1626], [#1627], [#1635], [#1638], [#1673], [#1675], [#1700], [#1717], [#1730], [#1749]) ([**@burgholzer**], [**@denialhaag**], [**@taminob**], [**@DRovara**], [**@li-mingbao**], [**@Ectras**], [**@MatthiasReumann**], [**@simon1hofmann**]) ### Changed @@ -402,6 +402,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool +[#1749]: https://github.com/munich-quantum-toolkit/core/pull/1749 [#1737]: https://github.com/munich-quantum-toolkit/core/pull/1737 [#1730]: https://github.com/munich-quantum-toolkit/core/pull/1730 [#1720]: https://github.com/munich-quantum-toolkit/core/pull/1720 From 68827a3a140fc543f370e2b8515928c2d49ed5bc Mon Sep 17 00:00:00 2001 From: Li-ming Bao Date: Wed, 27 May 2026 16:05:18 +0200 Subject: [PATCH 3/8] remove local setVector allocation --- mlir/lib/Conversion/QCToQCO/QCToQCO.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/mlir/lib/Conversion/QCToQCO/QCToQCO.cpp b/mlir/lib/Conversion/QCToQCO/QCToQCO.cpp index 08ef9f02d6..c04a3d2342 100644 --- a/mlir/lib/Conversion/QCToQCO/QCToQCO.cpp +++ b/mlir/lib/Conversion/QCToQCO/QCToQCO.cpp @@ -515,9 +515,6 @@ static void extractQubitsAfterOp(LoweringState& state, Operation* target, */ static std::pair, SetVector> collectQubitValuesInsideSCFOps(Operation* op, LoweringState* state) { - SetVector localQubits; - SetVector localRegisters; - // Helper to check if a qubit value is defined locally auto isDefinedLocally = [&](Region* region, Value value) { auto it = state->qubitInfoMap.find(region); @@ -540,36 +537,34 @@ collectQubitValuesInsideSCFOps(Operation* op, LoweringState* state) { collectQubitValuesInsideSCFOps(&operation, state); for (Value qubit : qubits) { if (!isDefinedLocally(®ion, qubit)) { - localQubits.insert(qubit); + state->regionQubitMap[op].insert(qubit); } } - localRegisters.set_union(registers); + state->regionRegisterMap[op].set_union(registers); } // Track qubits from loadOp if (auto loadOp = dyn_cast(operation)) { QubitInfo info{.reg = loadOp.getMemRef(), .index = loadOp.getIndices()[0]}; state->qubitInfoMap[®ion].try_emplace(loadOp.getResult(), info); - localRegisters.insert(loadOp.getMemRef()); + state->regionRegisterMap[op].insert(loadOp.getMemRef()); continue; } // Add the QC qubit and memref operands to the maps for (const auto& operand : operation.getOperands()) { if (isa(operand.getType())) { if (!isDefinedLocally(®ion, operand)) { - localQubits.insert(operand); + state->regionQubitMap[op].insert(operand); } } if (auto memref = dyn_cast(operand.getType())) { if (isa(memref.getElementType())) { - localRegisters.insert(operand); + state->regionRegisterMap[op].insert(operand); } } } } } - state->regionQubitMap[op].set_union(localQubits); - state->regionRegisterMap[op].set_union(localRegisters); return {state->regionQubitMap[op], state->regionRegisterMap[op]}; } From 023b4e74fab540f4ff214e6b012bd07d468f6ead Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer Date: Thu, 28 May 2026 11:58:40 +0200 Subject: [PATCH 4/8] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Reduce=20repeated=20ma?= =?UTF-8?q?p=20access?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lukas Burgholzer --- mlir/lib/Conversion/QCToQCO/QCToQCO.cpp | 31 +++++++++++-------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/mlir/lib/Conversion/QCToQCO/QCToQCO.cpp b/mlir/lib/Conversion/QCToQCO/QCToQCO.cpp index c04a3d2342..b4a4b0a151 100644 --- a/mlir/lib/Conversion/QCToQCO/QCToQCO.cpp +++ b/mlir/lib/Conversion/QCToQCO/QCToQCO.cpp @@ -515,12 +515,6 @@ static void extractQubitsAfterOp(LoweringState& state, Operation* target, */ static std::pair, SetVector> collectQubitValuesInsideSCFOps(Operation* op, LoweringState* state) { - // Helper to check if a qubit value is defined locally - auto isDefinedLocally = [&](Region* region, Value value) { - auto it = state->qubitInfoMap.find(region); - return it != state->qubitInfoMap.end() && it->second.contains(value); - }; - for (auto& region : op->getRegions()) { // Skip empty regions e.g. empty else region of an If operation if (region.empty()) { @@ -528,38 +522,41 @@ collectQubitValuesInsideSCFOps(Operation* op, LoweringState* state) { } // Check that the region has only one block assert(region.hasOneBlock() && "Expected single-block region"); - // Iterate through all operations of the current region for (auto& operation : region.front().getOperations()) { // Recursively walk through nested regions if (operation.getNumRegions() > 0) { auto [qubits, registers] = collectQubitValuesInsideSCFOps(&operation, state); - for (Value qubit : qubits) { - if (!isDefinedLocally(®ion, qubit)) { - state->regionQubitMap[op].insert(qubit); - } - } + auto& regionQubitMap = state->regionQubitMap[op]; + auto& qubitInfoMap = state->qubitInfoMap[®ion]; + regionQubitMap.set_union(qubits); + // Remove duplicate qubits + regionQubitMap.remove_if( + [&](Value qubit) { return qubitInfoMap.contains(qubit); }); state->regionRegisterMap[op].set_union(registers); } + auto& qubitInfoMap = state->qubitInfoMap[®ion]; + auto& regionRegisterMap = state->regionRegisterMap[op]; // Track qubits from loadOp if (auto loadOp = dyn_cast(operation)) { QubitInfo info{.reg = loadOp.getMemRef(), .index = loadOp.getIndices()[0]}; - state->qubitInfoMap[®ion].try_emplace(loadOp.getResult(), info); - state->regionRegisterMap[op].insert(loadOp.getMemRef()); + qubitInfoMap.try_emplace(loadOp.getResult(), info); + regionRegisterMap.insert(loadOp.getMemRef()); continue; } + auto& regionQubitMap = state->regionQubitMap[op]; // Add the QC qubit and memref operands to the maps for (const auto& operand : operation.getOperands()) { if (isa(operand.getType())) { - if (!isDefinedLocally(®ion, operand)) { - state->regionQubitMap[op].insert(operand); + if (!qubitInfoMap.contains(operand)) { + regionQubitMap.insert(operand); } } if (auto memref = dyn_cast(operand.getType())) { if (isa(memref.getElementType())) { - state->regionRegisterMap[op].insert(operand); + regionRegisterMap.insert(operand); } } } From 74808eafecdfbc6dcd80f3ebc2169ccd6dbf503b Mon Sep 17 00:00:00 2001 From: Li-ming Bao Date: Thu, 28 May 2026 14:25:40 +0200 Subject: [PATCH 5/8] add additional test to check dangling reference fix in conversion --- .../Conversion/QCOToQC/test_qco_to_qc.cpp | 9 ++++++--- .../Conversion/QCToQCO/test_qc_to_qco.cpp | 20 +++++++++++-------- mlir/unittests/programs/qc_programs.cpp | 9 +++++++++ mlir/unittests/programs/qc_programs.h | 3 +++ mlir/unittests/programs/qco_programs.cpp | 9 +++++++++ mlir/unittests/programs/qco_programs.h | 3 +++ 6 files changed, 42 insertions(+), 11 deletions(-) diff --git a/mlir/unittests/Conversion/QCOToQC/test_qco_to_qc.cpp b/mlir/unittests/Conversion/QCOToQC/test_qco_to_qc.cpp index fec35911b7..4bd2b24615 100644 --- a/mlir/unittests/Conversion/QCOToQC/test_qco_to_qc.cpp +++ b/mlir/unittests/Conversion/QCOToQC/test_qco_to_qc.cpp @@ -527,10 +527,13 @@ INSTANTIATE_TEST_SUITE_P( QCOToQCTestCase{"SingleControlledX", MQT_NAMED_BUILDER(qco::singleControlledX), MQT_NAMED_BUILDER(qc::singleControlledX)}, + QCOToQCTestCase{"MultipleControlledX", + MQT_NAMED_BUILDER(qco::multipleControlledX), + MQT_NAMED_BUILDER(qc::multipleControlledX)}, QCOToQCTestCase{ - "MultipleControlledX", - MQT_NAMED_BUILDER(qco::multipleControlledX), - MQT_NAMED_BUILDER(qc::multipleControlledX)})); + "RepeatedControlledX", + MQT_NAMED_BUILDER(qco::repeatedControlledX), + MQT_NAMED_BUILDER(qc::repeatedControlledX)})); /// @} /// \name QCOToQC/Operations/StandardGates/XxMinusYyOp.cpp diff --git a/mlir/unittests/Conversion/QCToQCO/test_qc_to_qco.cpp b/mlir/unittests/Conversion/QCToQCO/test_qc_to_qco.cpp index eff8c5ca12..3f0df25542 100644 --- a/mlir/unittests/Conversion/QCToQCO/test_qc_to_qco.cpp +++ b/mlir/unittests/Conversion/QCToQCO/test_qc_to_qco.cpp @@ -525,15 +525,19 @@ INSTANTIATE_TEST_SUITE_P( /// @{ INSTANTIATE_TEST_SUITE_P( QCXOpTest, QCToQCOTest, - testing::Values(QCToQCOTestCase{"X", MQT_NAMED_BUILDER(qc::x), - MQT_NAMED_BUILDER(qco::x)}, - QCToQCOTestCase{"SingleControlledX", - MQT_NAMED_BUILDER(qc::singleControlledX), - MQT_NAMED_BUILDER(qco::singleControlledX)}, - QCToQCOTestCase{ - "MultipleControlledX", + testing::Values( + QCToQCOTestCase{"X", MQT_NAMED_BUILDER(qc::x), + MQT_NAMED_BUILDER(qco::x)}, + QCToQCOTestCase{"SingleControlledX", + MQT_NAMED_BUILDER(qc::singleControlledX), + MQT_NAMED_BUILDER(qco::singleControlledX)}, + QCToQCOTestCase{"MultipleControlledX", MQT_NAMED_BUILDER(qc::multipleControlledX), - MQT_NAMED_BUILDER(qco::multipleControlledX)})); + MQT_NAMED_BUILDER(qco::multipleControlledX)}, + QCToQCOTestCase{"RepeatedControlledX", + MQT_NAMED_BUILDER(qc::repeatedControlledX), + MQT_NAMED_BUILDER(qco::repeatedControlledX)})); + /// @} /// \name QCToQCO/Operations/StandardGates/XxMinusYyOp.cpp diff --git a/mlir/unittests/programs/qc_programs.cpp b/mlir/unittests/programs/qc_programs.cpp index c6ba8b013f..82b5dbf150 100644 --- a/mlir/unittests/programs/qc_programs.cpp +++ b/mlir/unittests/programs/qc_programs.cpp @@ -271,6 +271,15 @@ void trivialControlledX(QCProgramBuilder& b) { b.mcx({}, q[0]); } +void repeatedControlledX(QCProgramBuilder& b) { + auto control = b.allocQubit(); + b.h(control); + for (auto i = 0; i < 50; i++) { + auto qubit = b.allocQubit(); + b.mcx(control, qubit); + } +} + void inverseX(QCProgramBuilder& b) { auto q = b.allocQubitRegister(1); b.inv([&]() { b.x(q[0]); }); diff --git a/mlir/unittests/programs/qc_programs.h b/mlir/unittests/programs/qc_programs.h index 124bb2be50..e6569f7648 100644 --- a/mlir/unittests/programs/qc_programs.h +++ b/mlir/unittests/programs/qc_programs.h @@ -171,6 +171,9 @@ void nestedControlledX(QCProgramBuilder& b); /// Creates a circuit with a trivial controlled X gate. void trivialControlledX(QCProgramBuilder& b); +/// Creates a circuit with repeated controlled X gates. +void repeatedControlledX(QCProgramBuilder& b); + /// Creates a circuit with an inverse modifier applied to an X gate. void inverseX(QCProgramBuilder& b); diff --git a/mlir/unittests/programs/qco_programs.cpp b/mlir/unittests/programs/qco_programs.cpp index afb5a6bf59..de49028ca6 100644 --- a/mlir/unittests/programs/qco_programs.cpp +++ b/mlir/unittests/programs/qco_programs.cpp @@ -271,6 +271,15 @@ void trivialControlledX(QCOProgramBuilder& b) { b.mcx({}, q[0]); } +void repeatedControlledX(QCOProgramBuilder& b) { + auto q0 = b.allocQubit(); + auto control = b.h(q0); + for (auto i = 0; i < 50; i++) { + auto qubit = b.allocQubit(); + control = b.mcx(control, qubit).first[0]; + } +} + void inverseX(QCOProgramBuilder& b) { auto q = b.allocQubitRegister(1); b.inv({q[0]}, [&](ValueRange qubits) { return SmallVector{b.x(qubits[0])}; }); diff --git a/mlir/unittests/programs/qco_programs.h b/mlir/unittests/programs/qco_programs.h index a056d91ca6..b4197c5a7f 100644 --- a/mlir/unittests/programs/qco_programs.h +++ b/mlir/unittests/programs/qco_programs.h @@ -158,6 +158,9 @@ void nestedControlledX(QCOProgramBuilder& b); /// Creates a circuit with a trivial controlled X gate. void trivialControlledX(QCOProgramBuilder& b); +/// Creates a circuit with repeated controlled X gates. +void repeatedControlledX(QCOProgramBuilder& b); + /// Creates a circuit with an inverse modifier applied to an X gate. void inverseX(QCOProgramBuilder& b); From ad129712f172c8317158041e38fd29ccd9ef910d Mon Sep 17 00:00:00 2001 From: Li-ming Bao Date: Thu, 28 May 2026 14:32:46 +0200 Subject: [PATCH 6/8] use cx operation instead of mcx --- mlir/unittests/programs/qc_programs.cpp | 2 +- mlir/unittests/programs/qco_programs.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/unittests/programs/qc_programs.cpp b/mlir/unittests/programs/qc_programs.cpp index 82b5dbf150..373452252a 100644 --- a/mlir/unittests/programs/qc_programs.cpp +++ b/mlir/unittests/programs/qc_programs.cpp @@ -276,7 +276,7 @@ void repeatedControlledX(QCProgramBuilder& b) { b.h(control); for (auto i = 0; i < 50; i++) { auto qubit = b.allocQubit(); - b.mcx(control, qubit); + b.cx(control, qubit); } } diff --git a/mlir/unittests/programs/qco_programs.cpp b/mlir/unittests/programs/qco_programs.cpp index de49028ca6..0ad96fbb10 100644 --- a/mlir/unittests/programs/qco_programs.cpp +++ b/mlir/unittests/programs/qco_programs.cpp @@ -276,7 +276,7 @@ void repeatedControlledX(QCOProgramBuilder& b) { auto control = b.h(q0); for (auto i = 0; i < 50; i++) { auto qubit = b.allocQubit(); - control = b.mcx(control, qubit).first[0]; + control = b.cx(control, qubit).first; } } From f3905dd0c2ad5ef5400df7150fe23322362e59d8 Mon Sep 17 00:00:00 2001 From: Li-ming Bao Date: Thu, 28 May 2026 15:24:58 +0200 Subject: [PATCH 7/8] add failing test --- .../Conversion/QCOToQC/test_qco_to_qc.cpp | 26 +++++++++++-------- .../Conversion/QCToQCO/test_qc_to_qco.cpp | 6 ++++- mlir/unittests/programs/qc_programs.cpp | 9 +++++++ mlir/unittests/programs/qc_programs.h | 4 +++ mlir/unittests/programs/qco_programs.cpp | 9 +++++++ mlir/unittests/programs/qco_programs.h | 4 +++ 6 files changed, 46 insertions(+), 12 deletions(-) diff --git a/mlir/unittests/Conversion/QCOToQC/test_qco_to_qc.cpp b/mlir/unittests/Conversion/QCOToQC/test_qco_to_qc.cpp index 4bd2b24615..9fb97ae594 100644 --- a/mlir/unittests/Conversion/QCOToQC/test_qco_to_qc.cpp +++ b/mlir/unittests/Conversion/QCOToQC/test_qco_to_qc.cpp @@ -522,18 +522,22 @@ INSTANTIATE_TEST_SUITE_P( /// @{ INSTANTIATE_TEST_SUITE_P( QCOXOpTest, QCOToQCTest, - testing::Values(QCOToQCTestCase{"X", MQT_NAMED_BUILDER(qco::x), - MQT_NAMED_BUILDER(qc::x)}, - QCOToQCTestCase{"SingleControlledX", - MQT_NAMED_BUILDER(qco::singleControlledX), - MQT_NAMED_BUILDER(qc::singleControlledX)}, - QCOToQCTestCase{"MultipleControlledX", - MQT_NAMED_BUILDER(qco::multipleControlledX), - MQT_NAMED_BUILDER(qc::multipleControlledX)}, - QCOToQCTestCase{ - "RepeatedControlledX", + testing::Values( + QCOToQCTestCase{"X", MQT_NAMED_BUILDER(qco::x), + MQT_NAMED_BUILDER(qc::x)}, + QCOToQCTestCase{"SingleControlledX", + MQT_NAMED_BUILDER(qco::singleControlledX), + MQT_NAMED_BUILDER(qc::singleControlledX)}, + QCOToQCTestCase{"MultipleControlledX", + MQT_NAMED_BUILDER(qco::multipleControlledX), + MQT_NAMED_BUILDER(qc::multipleControlledX)}, + QCOToQCTestCase{"RepeatedControlledX", MQT_NAMED_BUILDER(qco::repeatedControlledX), - MQT_NAMED_BUILDER(qc::repeatedControlledX)})); + MQT_NAMED_BUILDER(qc::repeatedControlledX)}, + QCOToQCTestCase{ + "RepeatedControlledXWithRegister", + MQT_NAMED_BUILDER(qco::repeatedControlledXWithRegister), + MQT_NAMED_BUILDER(qc::repeatedControlledXWithRegister)})); /// @} /// \name QCOToQC/Operations/StandardGates/XxMinusYyOp.cpp diff --git a/mlir/unittests/Conversion/QCToQCO/test_qc_to_qco.cpp b/mlir/unittests/Conversion/QCToQCO/test_qc_to_qco.cpp index 3f0df25542..171bc047b2 100644 --- a/mlir/unittests/Conversion/QCToQCO/test_qc_to_qco.cpp +++ b/mlir/unittests/Conversion/QCToQCO/test_qc_to_qco.cpp @@ -536,7 +536,11 @@ INSTANTIATE_TEST_SUITE_P( MQT_NAMED_BUILDER(qco::multipleControlledX)}, QCToQCOTestCase{"RepeatedControlledX", MQT_NAMED_BUILDER(qc::repeatedControlledX), - MQT_NAMED_BUILDER(qco::repeatedControlledX)})); + MQT_NAMED_BUILDER(qco::repeatedControlledX)}, + QCToQCOTestCase{ + "RepeatedControlledXWithRegister", + MQT_NAMED_BUILDER(qc::repeatedControlledXWithRegister), + MQT_NAMED_BUILDER(qco::repeatedControlledXWithRegister)})); /// @} diff --git a/mlir/unittests/programs/qc_programs.cpp b/mlir/unittests/programs/qc_programs.cpp index 373452252a..4db9591a10 100644 --- a/mlir/unittests/programs/qc_programs.cpp +++ b/mlir/unittests/programs/qc_programs.cpp @@ -280,6 +280,15 @@ void repeatedControlledX(QCProgramBuilder& b) { } } +void repeatedControlledXWithRegister(QCProgramBuilder& b) { + auto q = b.allocQubitRegister(50); + auto control = b.allocQubit(); + b.h(control); + for (auto i = 0; i < 50; i++) { + b.cx(control, q[i]); + } +} + void inverseX(QCProgramBuilder& b) { auto q = b.allocQubitRegister(1); b.inv([&]() { b.x(q[0]); }); diff --git a/mlir/unittests/programs/qc_programs.h b/mlir/unittests/programs/qc_programs.h index e6569f7648..0864154cce 100644 --- a/mlir/unittests/programs/qc_programs.h +++ b/mlir/unittests/programs/qc_programs.h @@ -174,6 +174,10 @@ void trivialControlledX(QCProgramBuilder& b); /// Creates a circuit with repeated controlled X gates. void repeatedControlledX(QCProgramBuilder& b); +/// Creates a circuit with repeated controlled X gates using qubits from a +/// register. +void repeatedControlledXWithRegister(QCProgramBuilder& b); + /// Creates a circuit with an inverse modifier applied to an X gate. void inverseX(QCProgramBuilder& b); diff --git a/mlir/unittests/programs/qco_programs.cpp b/mlir/unittests/programs/qco_programs.cpp index 0ad96fbb10..81684a4fe1 100644 --- a/mlir/unittests/programs/qco_programs.cpp +++ b/mlir/unittests/programs/qco_programs.cpp @@ -266,6 +266,15 @@ void nestedControlledX(QCOProgramBuilder& b) { }); } +void repeatedControlledXWithRegister(QCOProgramBuilder& b) { + auto q = b.allocQubitRegister(50); + auto q0 = b.allocQubit(); + auto control = b.h(q0); + for (auto i = 0; i < 50; i++) { + control = b.cx(control, q[i]).first; + } +} + void trivialControlledX(QCOProgramBuilder& b) { auto q = b.allocQubitRegister(1); b.mcx({}, q[0]); diff --git a/mlir/unittests/programs/qco_programs.h b/mlir/unittests/programs/qco_programs.h index b4197c5a7f..fcc1b9e859 100644 --- a/mlir/unittests/programs/qco_programs.h +++ b/mlir/unittests/programs/qco_programs.h @@ -161,6 +161,10 @@ void trivialControlledX(QCOProgramBuilder& b); /// Creates a circuit with repeated controlled X gates. void repeatedControlledX(QCOProgramBuilder& b); +/// Creates a circuit with repeated controlled X gates using qubits from a +/// register. +void repeatedControlledXWithRegister(QCOProgramBuilder& b); + /// Creates a circuit with an inverse modifier applied to an X gate. void inverseX(QCOProgramBuilder& b); From 4c2b99f1e71de216f0a3384fd4732783c125a941 Mon Sep 17 00:00:00 2001 From: Li-ming Bao Date: Fri, 29 May 2026 10:21:32 +0200 Subject: [PATCH 8/8] Revert "add failing test" This reverts commit f3905dd0c2ad5ef5400df7150fe23322362e59d8. --- .../Conversion/QCOToQC/test_qco_to_qc.cpp | 26 ++++++++----------- .../Conversion/QCToQCO/test_qc_to_qco.cpp | 6 +---- mlir/unittests/programs/qc_programs.cpp | 9 ------- mlir/unittests/programs/qc_programs.h | 4 --- mlir/unittests/programs/qco_programs.cpp | 9 ------- mlir/unittests/programs/qco_programs.h | 4 --- 6 files changed, 12 insertions(+), 46 deletions(-) diff --git a/mlir/unittests/Conversion/QCOToQC/test_qco_to_qc.cpp b/mlir/unittests/Conversion/QCOToQC/test_qco_to_qc.cpp index 9fb97ae594..4bd2b24615 100644 --- a/mlir/unittests/Conversion/QCOToQC/test_qco_to_qc.cpp +++ b/mlir/unittests/Conversion/QCOToQC/test_qco_to_qc.cpp @@ -522,22 +522,18 @@ INSTANTIATE_TEST_SUITE_P( /// @{ INSTANTIATE_TEST_SUITE_P( QCOXOpTest, QCOToQCTest, - testing::Values( - QCOToQCTestCase{"X", MQT_NAMED_BUILDER(qco::x), - MQT_NAMED_BUILDER(qc::x)}, - QCOToQCTestCase{"SingleControlledX", - MQT_NAMED_BUILDER(qco::singleControlledX), - MQT_NAMED_BUILDER(qc::singleControlledX)}, - QCOToQCTestCase{"MultipleControlledX", - MQT_NAMED_BUILDER(qco::multipleControlledX), - MQT_NAMED_BUILDER(qc::multipleControlledX)}, - QCOToQCTestCase{"RepeatedControlledX", + testing::Values(QCOToQCTestCase{"X", MQT_NAMED_BUILDER(qco::x), + MQT_NAMED_BUILDER(qc::x)}, + QCOToQCTestCase{"SingleControlledX", + MQT_NAMED_BUILDER(qco::singleControlledX), + MQT_NAMED_BUILDER(qc::singleControlledX)}, + QCOToQCTestCase{"MultipleControlledX", + MQT_NAMED_BUILDER(qco::multipleControlledX), + MQT_NAMED_BUILDER(qc::multipleControlledX)}, + QCOToQCTestCase{ + "RepeatedControlledX", MQT_NAMED_BUILDER(qco::repeatedControlledX), - MQT_NAMED_BUILDER(qc::repeatedControlledX)}, - QCOToQCTestCase{ - "RepeatedControlledXWithRegister", - MQT_NAMED_BUILDER(qco::repeatedControlledXWithRegister), - MQT_NAMED_BUILDER(qc::repeatedControlledXWithRegister)})); + MQT_NAMED_BUILDER(qc::repeatedControlledX)})); /// @} /// \name QCOToQC/Operations/StandardGates/XxMinusYyOp.cpp diff --git a/mlir/unittests/Conversion/QCToQCO/test_qc_to_qco.cpp b/mlir/unittests/Conversion/QCToQCO/test_qc_to_qco.cpp index 171bc047b2..3f0df25542 100644 --- a/mlir/unittests/Conversion/QCToQCO/test_qc_to_qco.cpp +++ b/mlir/unittests/Conversion/QCToQCO/test_qc_to_qco.cpp @@ -536,11 +536,7 @@ INSTANTIATE_TEST_SUITE_P( MQT_NAMED_BUILDER(qco::multipleControlledX)}, QCToQCOTestCase{"RepeatedControlledX", MQT_NAMED_BUILDER(qc::repeatedControlledX), - MQT_NAMED_BUILDER(qco::repeatedControlledX)}, - QCToQCOTestCase{ - "RepeatedControlledXWithRegister", - MQT_NAMED_BUILDER(qc::repeatedControlledXWithRegister), - MQT_NAMED_BUILDER(qco::repeatedControlledXWithRegister)})); + MQT_NAMED_BUILDER(qco::repeatedControlledX)})); /// @} diff --git a/mlir/unittests/programs/qc_programs.cpp b/mlir/unittests/programs/qc_programs.cpp index 4db9591a10..373452252a 100644 --- a/mlir/unittests/programs/qc_programs.cpp +++ b/mlir/unittests/programs/qc_programs.cpp @@ -280,15 +280,6 @@ void repeatedControlledX(QCProgramBuilder& b) { } } -void repeatedControlledXWithRegister(QCProgramBuilder& b) { - auto q = b.allocQubitRegister(50); - auto control = b.allocQubit(); - b.h(control); - for (auto i = 0; i < 50; i++) { - b.cx(control, q[i]); - } -} - void inverseX(QCProgramBuilder& b) { auto q = b.allocQubitRegister(1); b.inv([&]() { b.x(q[0]); }); diff --git a/mlir/unittests/programs/qc_programs.h b/mlir/unittests/programs/qc_programs.h index 0864154cce..e6569f7648 100644 --- a/mlir/unittests/programs/qc_programs.h +++ b/mlir/unittests/programs/qc_programs.h @@ -174,10 +174,6 @@ void trivialControlledX(QCProgramBuilder& b); /// Creates a circuit with repeated controlled X gates. void repeatedControlledX(QCProgramBuilder& b); -/// Creates a circuit with repeated controlled X gates using qubits from a -/// register. -void repeatedControlledXWithRegister(QCProgramBuilder& b); - /// Creates a circuit with an inverse modifier applied to an X gate. void inverseX(QCProgramBuilder& b); diff --git a/mlir/unittests/programs/qco_programs.cpp b/mlir/unittests/programs/qco_programs.cpp index 81684a4fe1..0ad96fbb10 100644 --- a/mlir/unittests/programs/qco_programs.cpp +++ b/mlir/unittests/programs/qco_programs.cpp @@ -266,15 +266,6 @@ void nestedControlledX(QCOProgramBuilder& b) { }); } -void repeatedControlledXWithRegister(QCOProgramBuilder& b) { - auto q = b.allocQubitRegister(50); - auto q0 = b.allocQubit(); - auto control = b.h(q0); - for (auto i = 0; i < 50; i++) { - control = b.cx(control, q[i]).first; - } -} - void trivialControlledX(QCOProgramBuilder& b) { auto q = b.allocQubitRegister(1); b.mcx({}, q[0]); diff --git a/mlir/unittests/programs/qco_programs.h b/mlir/unittests/programs/qco_programs.h index fcc1b9e859..b4197c5a7f 100644 --- a/mlir/unittests/programs/qco_programs.h +++ b/mlir/unittests/programs/qco_programs.h @@ -161,10 +161,6 @@ void trivialControlledX(QCOProgramBuilder& b); /// Creates a circuit with repeated controlled X gates. void repeatedControlledX(QCOProgramBuilder& b); -/// Creates a circuit with repeated controlled X gates using qubits from a -/// register. -void repeatedControlledXWithRegister(QCOProgramBuilder& b); - /// Creates a circuit with an inverse modifier applied to an X gate. void inverseX(QCOProgramBuilder& b);