@@ -183,7 +183,8 @@ struct GateDecompositionPattern final
183183 auto getUser = [](mlir::Value qubit,
184184 auto && filter) -> std::optional<UnitaryOpInterface> {
185185 if (qubit) {
186- auto userIt = qubit.getUsers ().begin ();
186+ auto users = qubit.getUsers ();
187+ auto userIt = users.begin ();
187188 // qubit may have more than one use if it is in a ctrl block (one use
188189 // for gate, one use for ctrl); we want to use the ctrl operation
189190 // since it is relevant for the total unitary matrix of the circuit
@@ -192,6 +193,10 @@ struct GateDecompositionPattern final
192193 // TODO: use wire iterator for proper handling
193194 while (!mlir::dyn_cast<CtrlOp>(*userIt)) {
194195 ++userIt;
196+ if (userIt == users.end ()) {
197+ // TODO: should not happen?
198+ return std::nullopt ;
199+ }
195200 }
196201 }
197202 auto user = mlir::dyn_cast<UnitaryOpInterface>(*userIt);
@@ -471,7 +476,7 @@ struct GateDecompositionPattern final
471476 inCtrlQubits.push_back (inQubits[gate.qubitId [1 ]]);
472477 }
473478 auto newGate = createControlledGate<XOp>(
474- rewriter, location, { inQubits[gate.qubitId [0 ]]}, inCtrlQubits );
479+ rewriter, location, inCtrlQubits, inQubits[gate.qubitId [0 ]]);
475480 updateInQubits (gate.qubitId , newGate);
476481 } else if (gate.type == qc::RX) {
477482 assert (gate.qubitId .size () == 1 );
@@ -501,6 +506,9 @@ struct GateDecompositionPattern final
501506 rewriter.replaceAllUsesWith (series.outQubits , inQubits);
502507 }
503508 for (auto && gate : llvm::reverse (series.gates )) {
509+ if (auto ctrlOp = llvm::dyn_cast<CtrlOp>(*gate.op )) {
510+ rewriter.eraseBlock (&ctrlOp.getBody ().front ());
511+ }
504512 rewriter.eraseOp (gate.op );
505513 }
506514 }
0 commit comments