Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
91b3ef9
feat(mlir): :sparkles: implement dead gate elimination canonicalizati…
DRovara Jun 1, 2026
ba57aa2
fix(mlir): :bug: fix tests
DRovara Jun 1, 2026
b83afab
test(mlir): :white_check_mark: add direct test for dead gate elimination
DRovara Jun 1, 2026
4243ac0
docs(mlir): :memo: update changelog
DRovara Jun 1, 2026
a50032b
style(mlir): :rotating_light: fix linter issues
DRovara Jun 1, 2026
d8c9ad5
fix(mlir): :recycle: guard RegionOp removal for child oeprations with…
DRovara Jun 2, 2026
9717547
fix(mlir): :bug: fix handling for `IfOp` removal and add specialized …
DRovara Jun 2, 2026
2d65418
fix(mlir): :bug: minor bug and code style fixes
DRovara Jun 2, 2026
278a54e
style(mlir): :rotating_light: fix linter issues on includes
DRovara Jun 2, 2026
44eaf7e
fix: :pencil2: fix typo in changelog
DRovara Jun 2, 2026
8b3af43
🎨 Optimize `checkAndRemoveDeadGate` function
burgholzer Jun 2, 2026
6998110
📝 Add to generic changelog entry for mqt-cc
burgholzer Jun 2, 2026
d56ccaf
Update mlir/lib/Dialect/QCO/IR/Operations/ResetOp.cpp
DRovara Jun 3, 2026
fb9fffb
🎨 pre-commit fixes
pre-commit-ci[bot] Jun 3, 2026
44f295a
test(mlir): :white_check_mark: improve test and add custom return typ…
DRovara Jun 3, 2026
9e8e711
Merge branch 'mlir/dead-gate-elimination' of github.com:munich-quantu…
DRovara Jun 3, 2026
b6cbf8e
style(mlir): :recycle: remove unneeded dumps
DRovara Jun 3, 2026
dee0752
style(mlir): :recycle: move `checkAndRemoveDeadGate` implementation o…
DRovara Jun 3, 2026
244f8bb
style(mlir): :recycle: implement helper function to check if a gate i…
DRovara Jun 3, 2026
6eaac40
style(mlir): :rotating_light: fix includes
DRovara Jun 3, 2026
07a3f4d
docs(mlir): :memo: add comments to document `gphase` operation as mem…
DRovara Jun 5, 2026
cab4155
test(mlir): :white_check_mark: update tests to now use return values
DRovara Jun 5, 2026
6f1c64e
Update mlir/include/mlir/Dialect/QCO/QCOUtils.h
DRovara Jun 8, 2026
7e63992
Update mlir/unittests/Dialect/QCO/IR/test_qco_ir.cpp
DRovara Jun 8, 2026
2e9f4e6
Update mlir/unittests/programs/qco_programs.cpp
DRovara Jun 8, 2026
29b0cbe
Update mlir/unittests/programs/qco_programs.h
DRovara Jun 8, 2026
225c88f
style(mlir): :recycle: address some review comments
DRovara Jun 8, 2026
4c5a22d
refactor(mlir): :recycle: remove old `build` method from QCOProgramBu…
DRovara Jun 11, 2026
fd40b82
feat(mlir): :recycle: add return types to `QCProgramBuilder`
DRovara Jun 11, 2026
e2ac131
feat(mlir): :recycle: update test programs for QC to also return retu…
DRovara Jun 11, 2026
2d70d31
Merge branch 'main' into mlir/dead-gate-elimination
DRovara Jun 23, 2026
88bac4e
chore(mlir): :construction: update QIR program builder and test system
DRovara Jun 23, 2026
8a519b8
feat(mlir): :white_check_mark: make all Compiler Pipeline tests pass
DRovara Jun 24, 2026
8726654
fix(mlir): :bug: fix issues with qco_ir_matrix
DRovara Jun 24, 2026
2851aee
test(mlir): :white_check_mark: pass QC->QCO and QC->QIR-Adaptive tests
DRovara Jun 25, 2026
304f530
fix(mlir): :bug: fix minor issue in `test_qco_ir` unittest
DRovara Jun 25, 2026
29d9627
test(mlir): :white_check_mark: pass QCO->QC tests
DRovara Jun 25, 2026
8ca4c96
test(mlir): :white_check_mark: pass quantum_computation translation t…
DRovara Jun 25, 2026
7ae3898
feat(mlir): :sparkles: update qc->qir conversion to handle return values
DRovara Jul 6, 2026
0567332
feat(mlir): :recycle: change default value of qir_programs template a…
DRovara Jul 6, 2026
bba85e8
fix: :bug: fix QuantumComputation python bindings for new parameter
DRovara Jul 6, 2026
62f1ab5
chore(mlir): :recycle: get rid of remaining helper files
DRovara Jul 6, 2026
fd72319
Merge branch 'main' into mlir/dead-gate-elimination
DRovara Jul 7, 2026
fc9a663
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 7, 2026
f18025b
fix(mlir): :bug: fix issues after merge
DRovara Jul 7, 2026
20426f8
Merge branch 'mlir/dead-gate-elimination' of github.com:munich-quantu…
DRovara Jul 7, 2026
afd395d
fix(mlir): :sparkles: fix leftover merging error
DRovara Jul 7, 2026
aeb9838
feat(mlir): :recycle: return QASM3 `output` values in resulting `QC` …
DRovara Jul 7, 2026
bb8152f
test(mlir): :sparkles: pass decomposition tests
DRovara Jul 7, 2026
973cf43
chore(mlir): :recycle: move implementation of dead gate removal to Si…
DRovara Jul 7, 2026
12aa9d1
feat(mlir): :sparkles: allow jeff translation to keep return values
DRovara Jul 7, 2026
ff48f93
fix(mlir): :rotating_light: potential fix to compiler error
DRovara Jul 7, 2026
dc89944
fix(mlir): :rotating_light: fix compiler issue by providing <> for de…
DRovara Jul 7, 2026
67d21dd
ci: :green_heart: add `--np-editable` to nox stubs session because it…
DRovara Jul 7, 2026
6dbd019
chore(mlir): :rotating_light: potential fix to most linter issues
DRovara Jul 7, 2026
b5fcbb0
fix(mlir): :rotating_light: fix compiler issue with imports
DRovara Jul 8, 2026
92eb0c7
fix(mlir): :recycle: fix some test errors and some linter issues
DRovara Jul 8, 2026
20468cf
fix(mlir): :bug: fix compilation error
DRovara Jul 8, 2026
5917c1b
fix(mlir): :bug: fix incorrect tests nad linter issues
DRovara Jul 8, 2026
21f01f0
fix(mlir): :bug: fix undefined behaviour
DRovara Jul 9, 2026
2b2d9b4
fix(mlir): :rotating_light: fix linter warnings
DRovara Jul 9, 2026
472361b
Merge branch 'main' into mlir/dead-gate-elimination
DRovara Jul 9, 2026
065d23a
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 9, 2026
98fafe6
test(mlir): :white_check_mark: pass new tests
DRovara Jul 9, 2026
224bf4a
Merge branch 'mlir/dead-gate-elimination' of github.com:munich-quantu…
DRovara Jul 9, 2026
5635099
test(mlir): :white_check_mark: fix incorrect test case
DRovara Jul 9, 2026
88d1886
Merge branch 'main' into mlir/dead-gate-elimination
DRovara Jul 9, 2026
a8e7acc
chore(mlir): :recycle: clean up further tests
DRovara Jul 9, 2026
6b53a71
Merge branch 'mlir/dead-gate-elimination' of github.com:munich-quantu…
DRovara Jul 9, 2026
af1009f
fix(mlir): :bug: fix build error in decomposition tests
DRovara Jul 9, 2026
1507296
chore(mlir): :recycle: potentially fix remaining linter errors
DRovara Jul 9, 2026
e327250
test(mlir): :recycle: increase test coverage for PR
DRovara Jul 9, 2026
7035f0d
chore(mlir): :recycle: apply coderabbit suggestions
DRovara Jul 9, 2026
915052d
fix(mlir): :bug: fix failing test
DRovara Jul 9, 2026
1dfe637
fix(mlir): :rotating_light: fix linter issue
DRovara Jul 9, 2026
360d849
test(mlir): :white_check_mark: improve coverage
DRovara Jul 9, 2026
56bf24b
Merge branch 'main' into mlir/dead-gate-elimination
DRovara Jul 9, 2026
3cc7522
:rewind: Revert change to noxfile that is no longer necessary
burgholzer Jul 9, 2026
a33d5d3
:fire: Use builtin functionality for mapping between IfOp operands an…
burgholzer Jul 9, 2026
a179e89
:truck: Move entry-point finder to common utils module
burgholzer Jul 9, 2026
4eba897
:children_crossing: Automatically deduce return types
burgholzer Jul 9, 2026
0139926
:children_crossing: Enable shortcut for single-return programs
burgholzer Jul 10, 2026
ec6777d
:art: Misc. improvements to QuantumComputation translation
burgholzer Jul 10, 2026
6ab9653
:art: Automatically infer return type in OQ3 translation
burgholzer Jul 10, 2026
0cd289a
:rotating_light: Fix linter warnings
burgholzer Jul 10, 2026
900c370
Merge branch 'main' into mlir/dead-gate-elimination
MatthiasReumann Jul 10, 2026
93b32c4
Use new builder API in mapping tests
MatthiasReumann Jul 10, 2026
75767b2
Add missing include
MatthiasReumann Jul 10, 2026
5a775ac
feat(mlir): :sparkles: report all qubits in Qasm3 if no output statem…
DRovara Jul 11, 2026
2db079d
test(mlir): :white_check_mark: simplify tests with new `output` handl…
DRovara Jul 11, 2026
5ba7983
Merge branch 'main' into mlir/dead-gate-elimination
DRovara Jul 11, 2026
36cf019
🎨 Streamline QASM programs
burgholzer Jul 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel

### Added

- ✨ Add Dead Gate Elimination Pattern ([#1755]) ([**DRovara**])
- 🚸 Add [CMake presets] to provide a standardized and reproducible way to configure builds ([#1660]) ([**@denialhaag**])
- ✨ Add a `quantum-loop-unroll` pass for unrolling for-loop operations containing quantum operations ([#1718]) ([**@MatthiasReumann**])
- ✨ Add a `hadamard-lifting` pass for lifting Hadamard gates above Pauli gates ([#1605]) ([**@lirem101**], [**@burgholzer**])
Expand Down Expand Up @@ -402,6 +403,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool

<!-- PR links -->

[#1755]: https://github.com/munich-quantum-toolkit/core/pull/1755
[#1749]: https://github.com/munich-quantum-toolkit/core/pull/1749
[#1748]: https://github.com/munich-quantum-toolkit/core/pull/1748
[#1737]: https://github.com/munich-quantum-toolkit/core/pull/1737
Expand Down
2 changes: 2 additions & 0 deletions mlir/include/mlir/Dialect/QCO/IR/QCODialect.td
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ def QCODialect : Dialect {
let cppNamespace = "::mlir::qco";

let useDefaultTypePrinterParser = 1;

let hasCanonicalizer = 1;
}

#endif // MLIR_DIALECT_QCO_IR_QCODIALECT_TD
229 changes: 118 additions & 111 deletions mlir/include/mlir/Dialect/QCO/IR/QCOOps.td

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions mlir/include/mlir/Dialect/QCO/QCOUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,42 @@ mergeTwoTargetOneParameterWithSwappedTargets(OpType op,
return success();
}

/**
* @brief Check if given quantum operation is unused (i.e., only used by
* sinks) and remove it if so.
*
* @param op The operation to check.
* @param rewriter The pattern rewriter.
* @return LogicalResult Success or failure of the removal.
*/
inline LogicalResult checkAndRemoveDeadGate(Operation* op,
PatternRewriter& rewriter) {
if (std::all_of(op->getUsers().begin(), op->getUsers().end(),
[](Operation* user) { return isa<SinkOp>(user); })) {
Comment thread
DRovara marked this conversation as resolved.
Outdated
// If the operation is only used by sinks, we can safely remove it.
if (auto u = dyn_cast<UnitaryOpInterface>(op)) {
// We specifically have to replace the output *qubits* with the input
// *qubits* to ignore parameters.
rewriter.replaceOp(op, u.getInputQubits());
return success();
} else if (auto m = dyn_cast<MeasureOp>(op)) {
// We specifically have to replace the output *qubits* with the input
// *qubits* to ignore the classical outcome.
rewriter.replaceAllUsesWith(m.getQubitOut(), m.getQubitIn());
rewriter.eraseOp(op);
return success();
} else if (auto i = dyn_cast<IfOp>(op)) {
// We specifically have to replace the output *qubits* with the input
// *qubits* to ignore the condition.
rewriter.replaceOp(op, i.getQubits());
return success();
} else {
// This currently only includes the `Reset` operation.
rewriter.replaceOp(op, op->getOperands());
return success();
}
}
return failure();
}

} // namespace mlir::qco
24 changes: 24 additions & 0 deletions mlir/lib/Dialect/QCO/IR/Operations/MeasureOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,31 @@
*/

#include "mlir/Dialect/QCO/IR/QCOOps.h"
#include "mlir/Dialect/QCO/QCOUtils.h"

#include <mlir/IR/MLIRContext.h>
#include <mlir/IR/PatternMatch.h>
#include <mlir/Support/LogicalResult.h>

using namespace mlir;
using namespace mlir::qco;

namespace {

/**
* @brief Remove dead measurements.
*/
struct DeadMeasurementRemoval final : OpRewritePattern<MeasureOp> {
using OpRewritePattern::OpRewritePattern;

LogicalResult matchAndRewrite(MeasureOp op,
PatternRewriter& rewriter) const override {
return checkAndRemoveDeadGate(op, rewriter);
}
};
Comment thread
burgholzer marked this conversation as resolved.
Outdated

} // namespace

LogicalResult MeasureOp::verify() {
const auto registerName = getRegisterName();
const auto registerSize = getRegisterSize();
Expand All @@ -37,3 +56,8 @@ LogicalResult MeasureOp::verify() {
}
return success();
}

void MeasureOp::getCanonicalizationPatterns(RewritePatternSet& results,
MLIRContext* context) {
results.add<DeadMeasurementRemoval>(context);
}
14 changes: 14 additions & 0 deletions mlir/lib/Dialect/QCO/IR/Operations/ResetOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/

#include "mlir/Dialect/QCO/IR/QCOOps.h"
#include "mlir/Dialect/QCO/QCOUtils.h"
#include "mlir/Dialect/QTensor/IR/QTensorOps.h"
#include "mlir/Dialect/QTensor/IR/QTensorUtils.h"

Expand Down Expand Up @@ -101,6 +102,18 @@ struct RemoveResetAfterExtract final : OpRewritePattern<ResetOp> {
}
};

/**
* @brief Remove dead resets.
*/
struct DeadResetRemoval final : OpRewritePattern<ResetOp> {
using OpRewritePattern::OpRewritePattern;

LogicalResult matchAndRewrite(ResetOp op,
PatternRewriter& rewriter) const override {
return checkAndRemoveDeadGate(op, rewriter);
}
};

} // namespace

OpFoldResult ResetOp::fold(FoldAdaptor /*adaptor*/) {
Expand All @@ -114,4 +127,5 @@ OpFoldResult ResetOp::fold(FoldAdaptor /*adaptor*/) {
void ResetOp::getCanonicalizationPatterns(RewritePatternSet& results,
MLIRContext* context) {
results.add<RemoveResetAfterExtract>(context);
results.add<DeadResetRemoval>(context);
Comment thread
DRovara marked this conversation as resolved.
Outdated
}
37 changes: 37 additions & 0 deletions mlir/lib/Dialect/QCO/IR/QCOOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,19 @@
#include "mlir/Dialect/QCO/IR/QCOOps.h"

#include "mlir/Dialect/QCO/IR/QCODialect.h" // IWYU pragma: associated
#include "mlir/Dialect/QCO/IR/QCOInterfaces.h"
#include "mlir/Dialect/QCO/QCOUtils.h"

#include <llvm/ADT/STLExtras.h>
#include <mlir/IR/Block.h>
#include <mlir/IR/MLIRContext.h>
#include <mlir/IR/OpImplementation.h>
#include <mlir/IR/Operation.h>
#include <mlir/IR/OperationSupport.h>
#include <mlir/IR/PatternMatch.h>
#include <mlir/IR/Region.h>
#include <mlir/IR/ValueRange.h>
#include <mlir/Interfaces/ShapedOpInterfaces.h>

Check warning on line 26 in mlir/lib/Dialect/QCO/IR/QCOOps.cpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

mlir/lib/Dialect/QCO/IR/QCOOps.cpp:26:1 [misc-include-cleaner]

included header ShapedOpInterfaces.h is not used directly
#include <mlir/Support/LLVM.h>

// The following headers are needed for some template instantiations.
Expand All @@ -30,6 +35,34 @@
using namespace mlir;
using namespace mlir::qco;

//===----------------------------------------------------------------------===//
// Dialect-Level Canonicalizers
//===----------------------------------------------------------------------===//

namespace {

/**
* @brief Remove dead measurements.
*/
struct DeadGateElimination final
: public OpInterfaceRewritePattern<UnitaryOpInterface> {

explicit DeadGateElimination(MLIRContext* context)
: OpInterfaceRewritePattern(context) {}

LogicalResult matchAndRewrite(UnitaryOpInterface op,
PatternRewriter& rewriter) const override {
if (!isMemoryEffectFree(op)) {

Check warning on line 55 in mlir/lib/Dialect/QCO/IR/QCOOps.cpp

View workflow job for this annotation

GitHub Actions / 🇨‌ Lint / 🚨 Lint

mlir/lib/Dialect/QCO/IR/QCOOps.cpp:55:10 [misc-include-cleaner]

no header providing "mlir::isMemoryEffectFree" is directly included
// This effectively ignores the GPhase operation and variants such as its
// inverse or `if` ops containing it, which should never be considered
// dead.
return failure();
}
return checkAndRemoveDeadGate(op.getOperation(), rewriter);
}
};
} // namespace

//===----------------------------------------------------------------------===//
// Custom Parsers
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -258,6 +291,10 @@
>();
}

void QCODialect::getCanonicalizationPatterns(RewritePatternSet& results) const {
results.add<DeadGateElimination>(getContext());
}

//===----------------------------------------------------------------------===//
// Types
//===----------------------------------------------------------------------===//
Expand Down
14 changes: 14 additions & 0 deletions mlir/lib/Dialect/QCO/IR/SCF/IfOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/

#include "mlir/Dialect/QCO/IR/QCOOps.h"
#include "mlir/Dialect/QCO/QCOUtils.h"

#include <llvm/ADT/STLExtras.h>
#include <llvm/ADT/STLFunctionalExtras.h>
Expand Down Expand Up @@ -234,11 +235,24 @@ struct ConditionPropagation : public OpRewritePattern<IfOp> {
return success(changed);
}
};

/**
* @brief Remove dead `IfOp` instructions.
*/
struct DeadIfRemoval final : OpRewritePattern<IfOp> {
using OpRewritePattern::OpRewritePattern;

LogicalResult matchAndRewrite(IfOp op,
PatternRewriter& rewriter) const override {
return checkAndRemoveDeadGate(op, rewriter);
Comment thread
DRovara marked this conversation as resolved.
Outdated
}
};
} // namespace

void IfOp::getCanonicalizationPatterns(RewritePatternSet& results,
MLIRContext* context) {
results.add<RemoveStaticCondition, ConditionPropagation>(context);
results.add<DeadIfRemoval>(context);
populateRegionBranchOpInterfaceCanonicalizationPatterns(
results, IfOp::getOperationName());
}
Expand Down
108 changes: 108 additions & 0 deletions mlir/unittests/Dialect/QCO/IR/test_qco_ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,114 @@ TEST_F(QCOTest, BuilderRejectsMixedStaticAndDynamicQubitAllocationModes) {
"Cannot mix dynamic and static qubit allocation modes");
}

TEST_F(QCOTest, CheckDeadGateElimination) {
Comment thread
burgholzer marked this conversation as resolved.
Outdated
QCOProgramBuilder builder(context.get());
builder.initialize();
auto q0S0 = builder.allocQubit();
auto q1S0 = builder.allocQubit();
auto q0S1 = builder.h(q0S0);
auto [q0S2, q1S1] = builder.cx(q0S1, q1S0);
auto [q1S2, c1] = builder.measure(q1S1);
builder.sink(q0S2);
builder.sink(q1S2);
auto module = builder.finalize();

QCOProgramBuilder reference(context.get());
reference.initialize();
auto r0 = reference.allocQubit();
auto r1 = reference.allocQubit();
reference.sink(r0);
reference.sink(r1);
Comment thread
burgholzer marked this conversation as resolved.
Outdated
auto refModule = reference.finalize();

ASSERT_TRUE(module);
EXPECT_TRUE(verify(*module).succeeded());
EXPECT_TRUE(runQCOCleanupPipeline(module.get()).succeeded());
EXPECT_TRUE(verify(*module).succeeded());

ASSERT_TRUE(refModule);
EXPECT_TRUE(verify(*refModule).succeeded());
EXPECT_TRUE(runQCOCleanupPipeline(refModule.get()).succeeded());
EXPECT_TRUE(verify(*refModule).succeeded());

EXPECT_TRUE(
areModulesEquivalentWithPermutations(module.get(), refModule.get()));
}

TEST_F(QCOTest, CheckIfOpDeadGateElimination) {
QCOProgramBuilder builder(context.get());
builder.initialize();
auto q0S0 = builder.allocQubit();
auto q1S0 = builder.allocQubit();
auto q0S1 = builder.h(q0S0);
auto [q0S2, c0] = builder.measure(q0S1);

// This is an `if` with memory effects - it can't be removed.
auto q1S1 = builder.qcoIf(
c0, {q1S0},
[&](ValueRange qubits) -> SmallVector<Value> {
auto q1Then = builder.x(qubits[0]);
builder.gphase(0.5);
return SmallVector<Value>{q1Then};
},
[&](ValueRange qubits) -> SmallVector<Value> {
auto q1Else = builder.h(qubits[0]);
return SmallVector<Value>{q1Else};
})[0];

// This is an `if` without memory effects - it can be removed.
auto q1S2 = builder.qcoIf(
c0, {q1S1},
[&](ValueRange qubits) -> SmallVector<Value> {
auto q1Then = builder.x(qubits[0]);
return SmallVector<Value>{q1Then};
},
[&](ValueRange qubits) -> SmallVector<Value> {
auto q1Else = builder.h(qubits[0]);
return SmallVector<Value>{q1Else};
})[0];
builder.sink(q0S2);
builder.sink(q1S2);
auto module = builder.finalize();

QCOProgramBuilder reference(context.get());
reference.initialize();
auto r0S0 = reference.allocQubit();
auto r1S0 = reference.allocQubit();
auto r0S1 = reference.h(r0S0);
auto [r0S2, cr0] = reference.measure(r0S1);

// This is an `if` with memory effects - it can't be removed.
auto r1S1 = reference.qcoIf(
cr0, {r1S0},
[&](ValueRange qubits) -> SmallVector<Value> {
auto q1Then = reference.x(qubits[0]);
reference.gphase(0.5);
return SmallVector<Value>{q1Then};
},
[&](ValueRange qubits) -> SmallVector<Value> {
auto q1Else = reference.h(qubits[0]);
return SmallVector<Value>{q1Else};
})[0];

reference.sink(r0S2);
reference.sink(r1S1);
auto refModule = reference.finalize();
Comment thread
burgholzer marked this conversation as resolved.
Outdated

ASSERT_TRUE(module);
EXPECT_TRUE(verify(*module).succeeded());
EXPECT_TRUE(runQCOCleanupPipeline(module.get()).succeeded());
EXPECT_TRUE(verify(*module).succeeded());

ASSERT_TRUE(refModule);
EXPECT_TRUE(verify(*refModule).succeeded());
EXPECT_TRUE(runQCOCleanupPipeline(refModule.get()).succeeded());
EXPECT_TRUE(verify(*refModule).succeeded());

EXPECT_TRUE(
areModulesEquivalentWithPermutations(module.get(), refModule.get()));
}

TEST_F(QCOTest, DirectIfBuilder) {
// Test If construction directly
QCOProgramBuilder builder(context.get());
Expand Down
Loading