From 33276f657f0df5fe0c91bea91639325b19b48465 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Tue, 9 Dec 2025 14:55:33 +0000 Subject: [PATCH 01/48] Added gridsynth pass --- tket/src/passes/gridsynth.rs | 366 +++++++++++++++++++++++++++++++++++ 1 file changed, 366 insertions(+) create mode 100644 tket/src/passes/gridsynth.rs diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs new file mode 100644 index 000000000..748be425a --- /dev/null +++ b/tket/src/passes/gridsynth.rs @@ -0,0 +1,366 @@ +//! TKET extension crate. +// +// TODO: These docs appear in the landing page of the crate documentation on docs.rs. +// Make sure to update them to reflect the details of your extension. + +use hugr_core::{IncomingPort, OutgoingPort}; +use itertools::Itertools; +use portgraph::Direction; +use rsgridsynth::config::config_from_theta_epsilon; +use rsgridsynth::gridsynth::gridsynth_gates; +use crate::extension::rotation::ConstRotation; +// use crate::hugr::ops::handle::NodeHandle; +use crate::{Hugr, hugr, op_matches}; +use crate::hugr::builder::{DFGBuilder, Dataflow, HugrBuilder}; +use crate::hugr::extension::prelude::{qb_t}; +use crate::hugr::HugrView; +use crate::hugr::hugr::hugrmut::HugrMut; +use crate::hugr::{Node, Port}; +use crate::hugr::types::Signature; +use crate::TketOp; +// use crate::passes::guppy::NormalizeGuppy; + + +/// Find the FuncDefn node for the Rz gate. +fn find_rz(hugr: &mut Hugr) -> Option { + for node in hugr.nodes() { + let op_type = HugrView::get_optype(hugr, node); + if op_matches(op_type, TketOp::Rz) { + return Some(node); + } + } + None +} +// TO DO: extend this function to find all RZ gates + +fn find_linked_incoming_ports(hugr: &mut Hugr, node: Node, port_idx: usize) -> Vec<(Node, Port)> { + let ports = hugr.node_inputs(node); + let collected_ports: Vec<_> = ports.collect(); + let linked_ports = hugr. + linked_ports(node, collected_ports[port_idx]); + let linked_ports: Vec<(Node, Port)> = linked_ports.collect(); + linked_ports +} + +/// find the output port and node linked to the input specified by `port_idz` for `node` +fn find_single_linked_output_by_index(hugr: &mut Hugr, node: Node, port_idx: usize) -> (Node, OutgoingPort) { + let ports = hugr.node_inputs(node); + let collected_ports: Vec<_> = ports.collect(); + let prev_node_and_port = hugr. + single_linked_output(node, collected_ports[port_idx]).unwrap(); + prev_node_and_port +} + + // for node in hugr.nodes() { + // let op_type = HugrView::get_optype(hugr, node); + // if op_type.is_dfg() { + // let dfg_node = node; + // for node in hugr.descendants(dfg_node) { + // let op_type = HugrView::get_optype(hugr, node); + // if op_type.is_output() { + // return Some(node); + // } + // } + // } + // } + // None + +// fn search4angle(prev_node: Node) { +// for (pos, node) in hugr.input_neighbours(prev_node).with_position() { +// // let mut is_first_neighbour = true; // for checking if node is first neighbour +// let op_type = hugr.get_optype(node); +// if op_type.is_const() { +// break +// } +// else if pos == itertools::Position::Only { +// let first_neighbour = node; + +// } +// // if first neighbour +// else if pos == itertools::Position::First { +// let first_neighbour = node; +// } +// // else if is last element of neighbour +// else if ps == itertools::Position::Last { + +// } +// } +// } + +/// Find the constant node containing the angle to be inputted to the Rz gate +fn find_angle_node(hugr: &mut Hugr, rz_node: Node) -> Node { + // find linked ports to the rz port where the angle will be inputted + // the port offset of the angle is known to be 1 for the rz gate. + let (mut prev_node, _) = find_single_linked_output_by_index(hugr, rz_node, 1); + + // SHORTCUT: specialise to simple hugrs with LoadConst preceded by const node + // TO DO: generalise the following + let linked_ports = find_linked_incoming_ports(hugr, prev_node, 0); + let angle_node = linked_ports[0].0; + + // recursively check input neighbours until a constant node is found, explicitly handling some + // specific edge cases where it may be a different constant + // loop { + // for (pos, node) in hugr.input_neighbours(prev_node).with_position() { + // // let mut is_first_neighbour = true; // for checking if node is first neighbour + // let op_type = hugr.get_optype(node); + // if op_type.is_const() { + // break; + // } + // else if pos == itertools::Position::Only { + // let first_neighbour = node; + // } + // // if first neighbour + // else if pos == itertools::Position::First { + // let first_neighbour = node; + // } + // // else if is last element of neighbour + // else if ps == itertools::Position::Last { + + // } + // } + // // for (pos, node) in hugr.input_neighbours(prev_node).with_position() { + // // // let mut is_first_neighbour = true; // for checking if node is first neighbour + // // let op_type = hugr.get_optype(node); + // // if op_type.is_const() { + // // break; + // // } + // // else if pos == itertools::Position::Only { + // // let first_neighbour = node; + // // } + // // // if first neighbour + // // else if pos == itertools::Position::First { + // // let first_neighbour = node; + // // } + // // // else if is last element of neighbour + // // else if ps == itertools::Position::Last { + + // // } + // // } + // } + + angle_node +} + +fn find_angle(hugr: &mut Hugr) -> f64 { + let rz_node = find_rz(hugr).unwrap(); + let angle_node = find_angle_node(hugr, rz_node); + let op_type = hugr.get_optype(angle_node); + let angle_const = op_type.as_const().unwrap(); + let angle_val = &angle_const.value; + let rot: &ConstRotation = angle_val.get_custom_value().unwrap(); + let angle = rot.to_radians(); + angle +} + +fn apply_gridsynth(hugr: &mut Hugr, epsilon: f64) -> String { + let theta = find_angle(hugr); + // The following parameters could be made user-specifiable. For simplicity, I fix them, for now + // let epsilon = 1e-1; // very low precision to allow easier visualisation for demo + let seed = 1234; + let verbose = false; + let mut gridsynth_config = config_from_theta_epsilon(theta, epsilon, seed, verbose); + let gates = gridsynth_gates(&mut gridsynth_config); + let gates = gates.gates; + gates +} + + +fn gridsynth_output_to_hugr(gates: &str) -> Hugr { + let qb_row = vec![qb_t(); 1]; // TO CHECK: will it cause issues to insert new qubit wire? + let mut h = DFGBuilder::new(Signature::new(qb_row.clone(), qb_row)).unwrap(); + + let mut prev_op = h.input(); + for gate in gates.chars() { + if gate == 'H' { + prev_op = h.add_dataflow_op(TketOp::H, prev_op.outputs()).unwrap(); + } + else if gate == 'S' { + prev_op = h.add_dataflow_op(TketOp::S, prev_op.outputs()).unwrap(); + } + else if gate == 'T' { + prev_op = h.add_dataflow_op(TketOp::T, prev_op.outputs()).unwrap(); + } + else if gate == 'W' { + break; // Ignoring global phases for now. + } + } + h.set_outputs(prev_op.outputs()).unwrap(); + let hugr = h.finish_hugr().unwrap(); + hugr.validate().unwrap_or_else(|e| panic!("{e}")); + println!("{}", hugr.mermaid_string()); + hugr +} + +fn destroy_path_to_angle_node(hugr: &mut Hugr, rz_node: Node) { + // find linked ports to the rz port where the angle will be inputted + // the port offset of the angle is known to be 1 for the rz gate. + let linked_ports = find_linked_incoming_ports(hugr, rz_node, 1); + let load_const_node = linked_ports[0].0; + + // SHORTCUT: specialise to simple hugrs with LoadConst preceded by const node + // TO DO: generalise the following + let linked_ports = find_linked_incoming_ports(hugr, load_const_node, 0); + let angle_node = linked_ports[0].0; + + hugr.remove_node(load_const_node); + hugr.remove_node(angle_node); + // println!("{}", hugr.mermaid_string()); +} + +/// get previous node that provided qubit to Rz gate +fn find_qubit_source(hugr: &mut Hugr, rz_node: Node) -> Node { + let linked_ports = find_linked_incoming_ports(hugr, rz_node, 0); + let prev_node = linked_ports[0].0; + prev_node +} + +/// Add a gridsynth gate to some previous node, which may or may not be a gridsynth gate, +/// and connect +fn add_gate_and_connect(hugr: &mut Hugr, prev_node: Node, op: hugr::ops::OpType, output_node: Node) -> Node { + let current_node = hugr.add_node_after(output_node, op); + let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); + // Assuming there were no outgoing ports to begin with when deciding port offset + let src_port = ports[0]; + let ports: Vec<_> = hugr.node_inputs(current_node).collect(); + let dst_port = ports[0]; + hugr.connect(prev_node, src_port, current_node, dst_port); + let prev_node = current_node; + prev_node +} + +fn find_dfg_output_node(hugr: &mut Hugr) -> Option { + for node in hugr.nodes() { + let op_type = hugr.get_optype(node); + if op_type.is_dfg() { + let dfg_node = node; + for node in hugr.descendants(dfg_node) { + let op_type = HugrView::get_optype(hugr, node); + if op_type.is_output() { + return Some(node); + } + } + } + } + None +} + +fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) { + // getting node that gave qubit to Rz gate + let mut prev_node = find_qubit_source(hugr, rz_node); + let dfg_output_node = find_dfg_output_node(hugr).unwrap(); + + hugr.remove_node(rz_node); + + // recursively adding next gate in gates to prev_node + for gate in gates.chars() { + if gate == 'H' { + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::H.into(), dfg_output_node); + } + else if gate == 'S' { + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::S.into(), dfg_output_node); + } + else if gate == 'T' { + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::T.into(), dfg_output_node); + } + else if gate == 'W' { + // find output node and connect it to node for previous gate + + let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); + // Assuming there were no outgoing ports to begin with when deciding port offset + let src_port = ports[0]; + let ports: Vec<_> = hugr.node_inputs(dfg_output_node).collect(); + let dst_port = ports[0]; + hugr.connect(prev_node, src_port, dfg_output_node, dst_port); + break; // Ignoring global phases for now. + } + } + hugr.validate().unwrap_or_else(|e| panic!("{e}")); +} + +/// Replace an Rz gate with the corresponding gates outputted by gridsynth +pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) { + let rz_node = find_rz(hugr).unwrap(); + let gates = apply_gridsynth(hugr, epsilon); + destroy_path_to_angle_node(hugr, rz_node); + replace_rz_with_gridsynth_output(hugr, rz_node, &gates); +} + +// TO DO: make compatible with Guppy hugrs. Right now, it will only work for simple hugrs not like the +// ones that guppy produces + + + +/// Example error. +#[derive(Debug, derive_more::Display, derive_more::Error)] +#[display("Example error: {message}")] +pub struct ExampleError { + message: String, +} + +// Test of example function +#[cfg(test)] +mod tests { + use std::fs::File; + use std::io::{BufReader, stdin}; + + use super::*; + + use hugr_core::extension::{ExtensionRegistry, PRELUDE}; + use hugr_core::std_extensions::{STD_REG, std_reg}; + use crate::hugr::builder::Container; + use crate::hugr::envelope::read_described_envelope; + use crate::hugr::ops::Value; + use crate::extension::rotation::ConstRotation; + use crate::hugr::package::Package; + use crate::hugr::algorithms::const_fold::constant_fold_pass; + + fn build_rz_only_circ() -> (Hugr, Node) { + let theta = 0.64; + let qb_row = vec![qb_t(); 1]; + let mut h = DFGBuilder::new(Signature::new(qb_row.clone(), qb_row)).unwrap(); + let [q_in] = h.input_wires_arr(); + + let constant = h.add_constant(Value::extension(ConstRotation::from_radians(theta).unwrap())); + let loaded_const = h.load_const(&constant); + let rz = h.add_dataflow_op(TketOp::Rz, [q_in, loaded_const]).unwrap(); + let _ = h.set_outputs(rz.outputs()); + let mut circ = h.finish_hugr().unwrap(); //(rz.outputs()).unwrap().into(); + println!("First mermaid string is: {}", circ.mermaid_string()); + circ.validate().unwrap_or_else(|e| panic!("{e}")); + let rz_node = find_rz(&mut circ).unwrap(); + (circ, rz_node) + } + + + #[test] + fn gridsynth_pass_successful() { + // This test is just to check if a panic occurs + let (mut circ, rz_node) = build_rz_only_circ(); + let epsilon: f64 = 1e-3; + // let gates = apply_gridsynth(&mut circ, epsilon); + // println!("{}", &gates); + apply_gridsynth_pass(&mut circ, epsilon); + // println!("{}", circ.mermaid_string()); + } + + #[test] + fn test_gridsynth_output_to_hugr() { + let epsilon = 1e-3; + let (mut circ, rz_node) = build_rz_only_circ(); + let gates = apply_gridsynth(&mut circ, epsilon); + gridsynth_output_to_hugr(&gates); + } + + #[test] + fn test_import_guppy_rz() { + // TODO: update the following path + let f = File::open("/home/kennycampbell/coding_projects/tket_gridsynth_ext/guppy_rz").unwrap(); + let reader = BufReader::new(f); + let registry = std_reg(); + let (_, mut imported_package) = read_described_envelope(reader, ®istry).unwrap(); + let mut imported_hugr = &mut imported_package.modules[0]; + constant_fold_pass(imported_hugr.as_mut()); + println!("{}", imported_hugr.mermaid_string()); + } +} From 0fa764e0763c1d480bf69bd2018602fedcb7c9c0 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Tue, 9 Dec 2025 14:57:37 +0000 Subject: [PATCH 02/48] Added rsgridsynth dependency --- Cargo.toml | 1 + tket/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index e8bead451..8b16facc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,6 +98,7 @@ cool_asserts = "2.0.4" zstd = "0.13.3" anyhow = "1.0.100" num-rational = "0.4.2" +rsgridsynth = { git = "https://github.com/qiskit-community/rsgridsynth.git"} [profile.release.package.tket-py] # Some configurations to reduce the size of tket wheels diff --git a/tket/Cargo.toml b/tket/Cargo.toml index cb683c11c..e57b09dc9 100644 --- a/tket/Cargo.toml +++ b/tket/Cargo.toml @@ -77,6 +77,7 @@ pest_derive = { workspace = true } zstd = { workspace = true, optional = true } anyhow = { workspace = true, optional = true } num-rational = { workspace = true } +rsgridsynth = { workspace = true } [dev-dependencies] From df9ad0835e79d1368af1ea3a1573516391d9468a Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Tue, 9 Dec 2025 15:00:30 +0000 Subject: [PATCH 03/48] Declared gridsynth as module --- tket/src/passes.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tket/src/passes.rs b/tket/src/passes.rs index 130f5be02..993254923 100644 --- a/tket/src/passes.rs +++ b/tket/src/passes.rs @@ -16,6 +16,8 @@ pub use guppy::NormalizeGuppy; pub mod pytket; pub use pytket::lower_to_pytket; +pub mod gridsynth; + pub mod tuple_unpack; #[allow(deprecated)] pub use tuple_unpack::find_tuple_unpack_rewrites; From c490e2920d2dc7a6f1a04d18693f11508af26d05 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Wed, 10 Dec 2025 12:21:10 +0000 Subject: [PATCH 04/48] Finding angle node of guppy function but not extracting angle --- tket/src/passes/gridsynth.rs | 181 +++++++++++++++++++++-------------- 1 file changed, 109 insertions(+), 72 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 748be425a..e8dcc5ad4 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -1,15 +1,8 @@ -//! TKET extension crate. -// -// TODO: These docs appear in the landing page of the crate documentation on docs.rs. -// Make sure to update them to reflect the details of your extension. - -use hugr_core::{IncomingPort, OutgoingPort}; -use itertools::Itertools; -use portgraph::Direction; +use hugr::NodeIndex; +use hugr_core:: OutgoingPort; use rsgridsynth::config::config_from_theta_epsilon; use rsgridsynth::gridsynth::gridsynth_gates; use crate::extension::rotation::ConstRotation; -// use crate::hugr::ops::handle::NodeHandle; use crate::{Hugr, hugr, op_matches}; use crate::hugr::builder::{DFGBuilder, Dataflow, HugrBuilder}; use crate::hugr::extension::prelude::{qb_t}; @@ -18,7 +11,8 @@ use crate::hugr::hugr::hugrmut::HugrMut; use crate::hugr::{Node, Port}; use crate::hugr::types::Signature; use crate::TketOp; -// use crate::passes::guppy::NormalizeGuppy; +use hugr::algorithms::ComposablePass; +use crate::passes::guppy::NormalizeGuppy; /// Find the FuncDefn node for the Rz gate. @@ -87,59 +81,40 @@ fn find_single_linked_output_by_index(hugr: &mut Hugr, node: Node, port_idx: usi // } // } -/// Find the constant node containing the angle to be inputted to the Rz gate +/// Find the constant node containing the angle to be inputted to the Rz gate. +/// It is assumed that `hugr` has had the NormalizeGuppy passes applied to it +/// prior to being applied fn find_angle_node(hugr: &mut Hugr, rz_node: Node) -> Node { // find linked ports to the rz port where the angle will be inputted // the port offset of the angle is known to be 1 for the rz gate. let (mut prev_node, _) = find_single_linked_output_by_index(hugr, rz_node, 1); + println!("Before loop, index is: {}", prev_node.index()); // SHORTCUT: specialise to simple hugrs with LoadConst preceded by const node // TO DO: generalise the following - let linked_ports = find_linked_incoming_ports(hugr, prev_node, 0); - let angle_node = linked_ports[0].0; - - // recursively check input neighbours until a constant node is found, explicitly handling some - // specific edge cases where it may be a different constant - // loop { - // for (pos, node) in hugr.input_neighbours(prev_node).with_position() { - // // let mut is_first_neighbour = true; // for checking if node is first neighbour - // let op_type = hugr.get_optype(node); - // if op_type.is_const() { - // break; - // } - // else if pos == itertools::Position::Only { - // let first_neighbour = node; - // } - // // if first neighbour - // else if pos == itertools::Position::First { - // let first_neighbour = node; - // } - // // else if is last element of neighbour - // else if ps == itertools::Position::Last { - - // } - // } - // // for (pos, node) in hugr.input_neighbours(prev_node).with_position() { - // // // let mut is_first_neighbour = true; // for checking if node is first neighbour - // // let op_type = hugr.get_optype(node); - // // if op_type.is_const() { - // // break; - // // } - // // else if pos == itertools::Position::Only { - // // let first_neighbour = node; - // // } - // // // if first neighbour - // // else if pos == itertools::Position::First { - // // let first_neighbour = node; - // // } - // // // else if is last element of neighbour - // // else if ps == itertools::Position::Last { - - // // } - // // } - // } - - angle_node + // let linked_ports = find_linked_incoming_ports(hugr, prev_node, 0); + // let angle_node = linked_ports[0].0; + + // as all of the NormalizeGuppy passes have been run on the `hugr` before it enters this function, + // and these passes include constant folding, we can assume that we can follow the 0th ports back + // to a constant node where the angle is defined. + let max_iterations = 10; + let mut ii = 0; + loop { + let (current_node, _) = find_single_linked_output_by_index(hugr, prev_node, 0); + let op_type = hugr.get_optype(current_node); + println!("{}", current_node.index()); + if op_type.is_const() { + println!("condition met"); + let angle_node = current_node; + return angle_node; + } + if ii >= max_iterations { + panic!("Angle finding failed"); // TO DO: improve error handling + } + prev_node = current_node; + ii += 1; + } } fn find_angle(hugr: &mut Hugr) -> f64 { @@ -148,6 +123,10 @@ fn find_angle(hugr: &mut Hugr) -> f64 { let op_type = hugr.get_optype(angle_node); let angle_const = op_type.as_const().unwrap(); let angle_val = &angle_const.value; + println!("angle val is {:?} with type {}", angle_val, angle_val.get_type()); + + // let angle_val = angle_val.get_type().value(); + println!("Value is {}", angle_val.value()); let rot: &ConstRotation = angle_val.get_custom_value().unwrap(); let angle = rot.to_radians(); angle @@ -280,6 +259,16 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) /// Replace an Rz gate with the corresponding gates outputted by gridsynth pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) { + // Running passes to convert HUGR to standard form + NormalizeGuppy::default() + .simplify_cfgs(true) + .remove_tuple_untuple(true) + .constant_folding(true) + .remove_dead_funcs(true) + .inline_dfgs(true) + .run(hugr) + .unwrap(); + let rz_node = find_rz(hugr).unwrap(); let gates = apply_gridsynth(hugr, epsilon); destroy_path_to_angle_node(hugr, rz_node); @@ -302,18 +291,15 @@ pub struct ExampleError { #[cfg(test)] mod tests { use std::fs::File; - use std::io::{BufReader, stdin}; + use std::io::BufReader; use super::*; - use hugr_core::extension::{ExtensionRegistry, PRELUDE}; - use hugr_core::std_extensions::{STD_REG, std_reg}; + use hugr_core::std_extensions::std_reg; use crate::hugr::builder::Container; use crate::hugr::envelope::read_described_envelope; use crate::hugr::ops::Value; use crate::extension::rotation::ConstRotation; - use crate::hugr::package::Package; - use crate::hugr::algorithms::const_fold::constant_fold_pass; fn build_rz_only_circ() -> (Hugr, Node) { let theta = 0.64; @@ -332,11 +318,22 @@ mod tests { (circ, rz_node) } + fn import_rz_only_guppy_circuit() -> Hugr { + // TODO: update the following path + let f = File::open("/home/kennycampbell/coding_projects/tket_gridsynth_ext/guppy_rz").unwrap(); + let reader = BufReader::new(f); + let registry = std_reg(); + let (_, imported_package) = read_described_envelope(reader, ®istry).unwrap(); + let imported_hugr = imported_package.modules[0].clone(); + println!("Before: {}", imported_hugr.mermaid_string()); + imported_hugr + } + #[test] fn gridsynth_pass_successful() { // This test is just to check if a panic occurs - let (mut circ, rz_node) = build_rz_only_circ(); + let (mut circ, _) = build_rz_only_circ(); let epsilon: f64 = 1e-3; // let gates = apply_gridsynth(&mut circ, epsilon); // println!("{}", &gates); @@ -347,20 +344,60 @@ mod tests { #[test] fn test_gridsynth_output_to_hugr() { let epsilon = 1e-3; - let (mut circ, rz_node) = build_rz_only_circ(); + let (mut circ, _) = build_rz_only_circ(); let gates = apply_gridsynth(&mut circ, epsilon); gridsynth_output_to_hugr(&gates); } #[test] - fn test_import_guppy_rz() { - // TODO: update the following path - let f = File::open("/home/kennycampbell/coding_projects/tket_gridsynth_ext/guppy_rz").unwrap(); - let reader = BufReader::new(f); - let registry = std_reg(); - let (_, mut imported_package) = read_described_envelope(reader, ®istry).unwrap(); - let mut imported_hugr = &mut imported_package.modules[0]; - constant_fold_pass(imported_hugr.as_mut()); - println!("{}", imported_hugr.mermaid_string()); + fn found_rz_guppy() { + let epsilon = 1e-2; + let mut imported_hugr = &mut import_rz_only_guppy_circuit(); + NormalizeGuppy::default() + .simplify_cfgs(true) + .remove_tuple_untuple(true) + .constant_folding(true) + .remove_dead_funcs(true) + .inline_dfgs(true) + .run(imported_hugr) + .unwrap(); + let rz_node = find_rz(imported_hugr).unwrap(); + assert_eq!(rz_node.index(), 17) + } + + #[test] + fn test_find_angle_node_for_guppy() { + let epsilon = 1e-2; + let mut imported_hugr = &mut import_rz_only_guppy_circuit(); + NormalizeGuppy::default() + .simplify_cfgs(true) + .remove_tuple_untuple(true) + .constant_folding(true) + .remove_dead_funcs(true) + .inline_dfgs(true) + .run(imported_hugr) + .unwrap(); + let rz_node = find_rz(imported_hugr).unwrap(); + let angle_node = find_angle_node(imported_hugr, rz_node); + assert_eq!(angle_node.index(), 20); + + } + + #[test] + fn test_with_guppy_hugr() { + let epsilon = 1e-2; + let mut imported_hugr = &mut import_rz_only_guppy_circuit(); + NormalizeGuppy::default() + .simplify_cfgs(true) + .remove_tuple_untuple(true) + .constant_folding(true) + .remove_dead_funcs(true) + .inline_dfgs(true) + .run(imported_hugr) + .unwrap(); + // constant_fold_pass(imported_hugr.as_mut()); + // println!("after {}", imported_hugr.mermaid_string()); + apply_gridsynth_pass(&mut imported_hugr, epsilon); + println!("after: {}", imported_hugr.mermaid_string()); } } From a02ab9b1f5e0246ffe0b03bcfb093838075c67a9 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Wed, 10 Dec 2025 16:00:10 +0000 Subject: [PATCH 05/48] Extracting angle successfully --- tket/src/passes/gridsynth.rs | 47 +++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index e8dcc5ad4..50b09d117 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -12,7 +12,8 @@ use crate::hugr::{Node, Port}; use crate::hugr::types::Signature; use crate::TketOp; use hugr::algorithms::ComposablePass; -use crate::passes::guppy::NormalizeGuppy; +use hugr::std_extensions::arithmetic::float_types::ConstF64; +use crate::passes::guppy::NormalizeGuppy; /// Find the FuncDefn node for the Rz gate. @@ -90,11 +91,6 @@ fn find_angle_node(hugr: &mut Hugr, rz_node: Node) -> Node { let (mut prev_node, _) = find_single_linked_output_by_index(hugr, rz_node, 1); println!("Before loop, index is: {}", prev_node.index()); - // SHORTCUT: specialise to simple hugrs with LoadConst preceded by const node - // TO DO: generalise the following - // let linked_ports = find_linked_incoming_ports(hugr, prev_node, 0); - // let angle_node = linked_ports[0].0; - // as all of the NormalizeGuppy passes have been run on the `hugr` before it enters this function, // and these passes include constant folding, we can assume that we can follow the 0th ports back // to a constant node where the angle is defined. @@ -123,12 +119,42 @@ fn find_angle(hugr: &mut Hugr) -> f64 { let op_type = hugr.get_optype(angle_node); let angle_const = op_type.as_const().unwrap(); let angle_val = &angle_const.value; + let angle_type = angle_val.get_type(); + // let angle_type = angle_type.as_extension(); + // match angle_type. + // println!("sum is: {:?}", angle_val.get_custom_value()); + println!("extensions are: {:?}", angle_type); + // match angle_type { + // float64 => { + + // }, + + // } println!("angle val is {:?} with type {}", angle_val, angle_val.get_type()); - + // println!("value is {}", angle_val::value); + // println!("Custom val is: {:?}", angle_val.value()); + // if angle_type == 'float64' { + + // } // let angle_val = angle_val.get_type().value(); - println!("Value is {}", angle_val.value()); - let rot: &ConstRotation = angle_val.get_custom_value().unwrap(); - let angle = rot.to_radians(); + // println!("Value is {}", angle_val.value()); + // let custom_val: Option<&dyn CustomConst> = angle_val.get_custom_value(); + // let rot= match custom_val { + // None => None, + // Some(custom_val) => Some(custom_val), + // }; + // println!("{:?}", rot); + + let angle = if let Some(rot) = angle_val.get_custom_value::() { + rot.to_radians() + } else if let Some(fl) = angle_val.get_custom_value::() { + let half_turns = fl.value(); + ConstRotation::new(half_turns).unwrap().to_radians() + } else { + panic!("Angle not specified as ConstRotation or ConstF64") + }; + // let angle = rot.to_radians(); + println!("{}", angle); angle } @@ -380,7 +406,6 @@ mod tests { let rz_node = find_rz(imported_hugr).unwrap(); let angle_node = find_angle_node(imported_hugr, rz_node); assert_eq!(angle_node.index(), 20); - } #[test] From 946f6b8fa4775caeadb14d0248673fbd44bf3bb8 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Wed, 10 Dec 2025 16:30:54 +0000 Subject: [PATCH 06/48] Added clean up when finding angle_node and angle --- tket/src/passes/gridsynth.rs | 106 ++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 19 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 50b09d117..3681f4fb5 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -84,12 +84,13 @@ fn find_single_linked_output_by_index(hugr: &mut Hugr, node: Node, port_idx: usi /// Find the constant node containing the angle to be inputted to the Rz gate. /// It is assumed that `hugr` has had the NormalizeGuppy passes applied to it -/// prior to being applied +/// prior to being applied. This function also cleans up behind itself removing +/// everything on the path to the `angle_node` but not the `angle_node` itself, +/// which is still needed. fn find_angle_node(hugr: &mut Hugr, rz_node: Node) -> Node { // find linked ports to the rz port where the angle will be inputted // the port offset of the angle is known to be 1 for the rz gate. let (mut prev_node, _) = find_single_linked_output_by_index(hugr, rz_node, 1); - println!("Before loop, index is: {}", prev_node.index()); // as all of the NormalizeGuppy passes have been run on the `hugr` before it enters this function, // and these passes include constant folding, we can assume that we can follow the 0th ports back @@ -101,15 +102,20 @@ fn find_angle_node(hugr: &mut Hugr, rz_node: Node) -> Node { let op_type = hugr.get_optype(current_node); println!("{}", current_node.index()); if op_type.is_const() { - println!("condition met"); + hugr.remove_node(prev_node); let angle_node = current_node; return angle_node; } if ii >= max_iterations { panic!("Angle finding failed"); // TO DO: improve error handling } + + // Deleting all but nodes on the way to the rz_node but not the rz_node itself + hugr.remove_node(prev_node); + prev_node = current_node; ii += 1; + } } @@ -153,7 +159,10 @@ fn find_angle(hugr: &mut Hugr) -> f64 { } else { panic!("Angle not specified as ConstRotation or ConstF64") }; - // let angle = rot.to_radians(); + + // we now have what we need to know from the angle node and can remove it from the hugr + hugr.remove_node(angle_node); + println!("{}", angle); angle } @@ -197,21 +206,64 @@ fn gridsynth_output_to_hugr(gates: &str) -> Hugr { hugr } -fn destroy_path_to_angle_node(hugr: &mut Hugr, rz_node: Node) { - // find linked ports to the rz port where the angle will be inputted - // the port offset of the angle is known to be 1 for the rz gate. - let linked_ports = find_linked_incoming_ports(hugr, rz_node, 1); - let load_const_node = linked_ports[0].0; + // let (mut prev_node, _) = find_single_linked_output_by_index(hugr, rz_node, 1); + // println!("Before loop, index is: {}", prev_node.index()); + + // // as all of the NormalizeGuppy passes have been run on the `hugr` before it enters this function, + // // and these passes include constant folding, we can assume that we can follow the 0th ports back + // // to a constant node where the angle is defined. + // let max_iterations = 10; + // let mut ii = 0; + // loop { + // let (current_node, _) = find_single_linked_output_by_index(hugr, prev_node, 0); + // let op_type = hugr.get_optype(current_node); + // println!("{}", current_node.index()); + // if op_type.is_const() { + // println!("condition met"); + // let angle_node = current_node; + // return angle_node; + // } + // if ii >= max_iterations { + // panic!("Angle finding failed"); // TO DO: improve error handling + // } + // prev_node = current_node; + // ii += 1; + // } - // SHORTCUT: specialise to simple hugrs with LoadConst preceded by const node - // TO DO: generalise the following - let linked_ports = find_linked_incoming_ports(hugr, load_const_node, 0); - let angle_node = linked_ports[0].0; +// fn destroy_path_to_angle_node(hugr: &mut Hugr, rz_node: Node) { +// // find linked ports to the rz port where the angle will be inputted +// // the port offset of the angle is known to be 1 for the rz gate. +// // let linked_ports = find_linked_incoming_ports(hugr, rz_node, 1); +// // let load_const_node = linked_ports[0].0; + +// let (mut prev_node, _) = find_single_linked_output_by_index(hugr, rz_node, 1); +// println!("Before loop, index is: {}", prev_node.index()); + +// // as all of the NormalizeGuppy passes have been run on the `hugr` before it enters this function, +// // and these passes include constant folding, we can assume that we can follow the 0th ports back +// // to a constant node where the angle is defined. +// let max_iterations = 10; +// let mut ii = 0; +// loop { +// let (current_node, _) = find_single_linked_output_by_index(hugr, prev_node, 0); +// let op_type = hugr.get_optype(current_node); +// println!("{}", current_node.index()); +// if op_type.is_const() { +// println!("condition met"); +// let angle_node = current_node; +// return angle_node; +// } +// if ii >= max_iterations { +// panic!("Angle finding failed"); // TO DO: improve error handling +// } +// prev_node = current_node; +// ii += 1; +// } - hugr.remove_node(load_const_node); - hugr.remove_node(angle_node); +// hugr.remove_node(load_const_node); +// hugr.remove_node(angle_node); // println!("{}", hugr.mermaid_string()); -} +// } /// get previous node that provided qubit to Rz gate fn find_qubit_source(hugr: &mut Hugr, rz_node: Node) -> Node { @@ -297,7 +349,7 @@ pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) { let rz_node = find_rz(hugr).unwrap(); let gates = apply_gridsynth(hugr, epsilon); - destroy_path_to_angle_node(hugr, rz_node); + // destroy_path_to_angle_node(hugr, rz_node); replace_rz_with_gridsynth_output(hugr, rz_node, &gates); } @@ -393,8 +445,7 @@ mod tests { #[test] fn test_find_angle_node_for_guppy() { - let epsilon = 1e-2; - let mut imported_hugr = &mut import_rz_only_guppy_circuit(); + let imported_hugr = &mut import_rz_only_guppy_circuit(); NormalizeGuppy::default() .simplify_cfgs(true) .remove_tuple_untuple(true) @@ -408,6 +459,23 @@ mod tests { assert_eq!(angle_node.index(), 20); } + #[test] + fn test_find_angle_for_guppy() { + let imported_hugr = &mut import_rz_only_guppy_circuit(); + NormalizeGuppy::default() + .simplify_cfgs(true) + .remove_tuple_untuple(true) + .constant_folding(true) + .remove_dead_funcs(true) + .inline_dfgs(true) + .run(imported_hugr) + .unwrap(); + let rz_node = find_rz(imported_hugr).unwrap(); + let angle = find_angle(imported_hugr); + println!("angle is {}", angle); + println!("hugr is {}", imported_hugr.mermaid_string()); + } + #[test] fn test_with_guppy_hugr() { let epsilon = 1e-2; From e7430cd064c1aaea9619215a30f8ed31979fe47c Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Wed, 10 Dec 2025 16:45:35 +0000 Subject: [PATCH 07/48] Removed commented out code --- tket/src/passes/gridsynth.rs | 60 ------------------------------------ 1 file changed, 60 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 3681f4fb5..ab9bce49a 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -206,64 +206,6 @@ fn gridsynth_output_to_hugr(gates: &str) -> Hugr { hugr } - // let (mut prev_node, _) = find_single_linked_output_by_index(hugr, rz_node, 1); - // println!("Before loop, index is: {}", prev_node.index()); - - // // as all of the NormalizeGuppy passes have been run on the `hugr` before it enters this function, - // // and these passes include constant folding, we can assume that we can follow the 0th ports back - // // to a constant node where the angle is defined. - // let max_iterations = 10; - // let mut ii = 0; - // loop { - // let (current_node, _) = find_single_linked_output_by_index(hugr, prev_node, 0); - // let op_type = hugr.get_optype(current_node); - // println!("{}", current_node.index()); - // if op_type.is_const() { - // println!("condition met"); - // let angle_node = current_node; - // return angle_node; - // } - // if ii >= max_iterations { - // panic!("Angle finding failed"); // TO DO: improve error handling - // } - // prev_node = current_node; - // ii += 1; - // } - -// fn destroy_path_to_angle_node(hugr: &mut Hugr, rz_node: Node) { -// // find linked ports to the rz port where the angle will be inputted -// // the port offset of the angle is known to be 1 for the rz gate. -// // let linked_ports = find_linked_incoming_ports(hugr, rz_node, 1); -// // let load_const_node = linked_ports[0].0; - -// let (mut prev_node, _) = find_single_linked_output_by_index(hugr, rz_node, 1); -// println!("Before loop, index is: {}", prev_node.index()); - -// // as all of the NormalizeGuppy passes have been run on the `hugr` before it enters this function, -// // and these passes include constant folding, we can assume that we can follow the 0th ports back -// // to a constant node where the angle is defined. -// let max_iterations = 10; -// let mut ii = 0; -// loop { -// let (current_node, _) = find_single_linked_output_by_index(hugr, prev_node, 0); -// let op_type = hugr.get_optype(current_node); -// println!("{}", current_node.index()); -// if op_type.is_const() { -// println!("condition met"); -// let angle_node = current_node; -// return angle_node; -// } -// if ii >= max_iterations { -// panic!("Angle finding failed"); // TO DO: improve error handling -// } -// prev_node = current_node; -// ii += 1; -// } - -// hugr.remove_node(load_const_node); -// hugr.remove_node(angle_node); - // println!("{}", hugr.mermaid_string()); -// } /// get previous node that provided qubit to Rz gate fn find_qubit_source(hugr: &mut Hugr, rz_node: Node) -> Node { @@ -349,7 +291,6 @@ pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) { let rz_node = find_rz(hugr).unwrap(); let gates = apply_gridsynth(hugr, epsilon); - // destroy_path_to_angle_node(hugr, rz_node); replace_rz_with_gridsynth_output(hugr, rz_node, &gates); } @@ -470,7 +411,6 @@ mod tests { .inline_dfgs(true) .run(imported_hugr) .unwrap(); - let rz_node = find_rz(imported_hugr).unwrap(); let angle = find_angle(imported_hugr); println!("angle is {}", angle); println!("hugr is {}", imported_hugr.mermaid_string()); From 689f24cf2444f120286f634a7b58ce8edf4ec7d1 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Wed, 10 Dec 2025 17:27:08 +0000 Subject: [PATCH 08/48] Swithed to get_io from custom function --- tket/src/passes/gridsynth.rs | 61 ++++++------------------------------ 1 file changed, 10 insertions(+), 51 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index ab9bce49a..fd58e76ef 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -100,7 +100,6 @@ fn find_angle_node(hugr: &mut Hugr, rz_node: Node) -> Node { loop { let (current_node, _) = find_single_linked_output_by_index(hugr, prev_node, 0); let op_type = hugr.get_optype(current_node); - println!("{}", current_node.index()); if op_type.is_const() { hugr.remove_node(prev_node); let angle_node = current_node; @@ -125,32 +124,8 @@ fn find_angle(hugr: &mut Hugr) -> f64 { let op_type = hugr.get_optype(angle_node); let angle_const = op_type.as_const().unwrap(); let angle_val = &angle_const.value; - let angle_type = angle_val.get_type(); - // let angle_type = angle_type.as_extension(); - // match angle_type. - // println!("sum is: {:?}", angle_val.get_custom_value()); - println!("extensions are: {:?}", angle_type); - // match angle_type { - // float64 => { - - // }, - - // } - println!("angle val is {:?} with type {}", angle_val, angle_val.get_type()); - // println!("value is {}", angle_val::value); - // println!("Custom val is: {:?}", angle_val.value()); - // if angle_type == 'float64' { - - // } - // let angle_val = angle_val.get_type().value(); - // println!("Value is {}", angle_val.value()); - // let custom_val: Option<&dyn CustomConst> = angle_val.get_custom_value(); - // let rot= match custom_val { - // None => None, - // Some(custom_val) => Some(custom_val), - // }; - // println!("{:?}", rot); + // handling likely angle formats. Panic if angle is not one of the anticipated formats let angle = if let Some(rot) = angle_val.get_custom_value::() { rot.to_radians() } else if let Some(fl) = angle_val.get_custom_value::() { @@ -163,7 +138,6 @@ fn find_angle(hugr: &mut Hugr) -> f64 { // we now have what we need to know from the angle node and can remove it from the hugr hugr.remove_node(angle_node); - println!("{}", angle); angle } @@ -202,7 +176,6 @@ fn gridsynth_output_to_hugr(gates: &str) -> Hugr { h.set_outputs(prev_op.outputs()).unwrap(); let hugr = h.finish_hugr().unwrap(); hugr.validate().unwrap_or_else(|e| panic!("{e}")); - println!("{}", hugr.mermaid_string()); hugr } @@ -228,39 +201,26 @@ fn add_gate_and_connect(hugr: &mut Hugr, prev_node: Node, op: hugr::ops::OpType, prev_node } -fn find_dfg_output_node(hugr: &mut Hugr) -> Option { - for node in hugr.nodes() { - let op_type = hugr.get_optype(node); - if op_type.is_dfg() { - let dfg_node = node; - for node in hugr.descendants(dfg_node) { - let op_type = HugrView::get_optype(hugr, node); - if op_type.is_output() { - return Some(node); - } - } - } - } - None -} fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) { // getting node that gave qubit to Rz gate let mut prev_node = find_qubit_source(hugr, rz_node); - let dfg_output_node = find_dfg_output_node(hugr).unwrap(); + let parent = hugr.get_parent(rz_node).unwrap(); + let output_node = hugr.get_io(parent).unwrap()[1]; + // let dfg_output_node = find_sibling_output(hugr).unwrap(); hugr.remove_node(rz_node); // recursively adding next gate in gates to prev_node for gate in gates.chars() { if gate == 'H' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::H.into(), dfg_output_node); + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::H.into(), output_node); } else if gate == 'S' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::S.into(), dfg_output_node); + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::S.into(), output_node); } else if gate == 'T' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::T.into(), dfg_output_node); + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::T.into(), output_node); } else if gate == 'W' { // find output node and connect it to node for previous gate @@ -268,9 +228,9 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); // Assuming there were no outgoing ports to begin with when deciding port offset let src_port = ports[0]; - let ports: Vec<_> = hugr.node_inputs(dfg_output_node).collect(); + let ports: Vec<_> = hugr.node_inputs(output_node).collect(); let dst_port = ports[0]; - hugr.connect(prev_node, src_port, dfg_output_node, dst_port); + hugr.connect(prev_node, src_port, output_node, dst_port); break; // Ignoring global phases for now. } } @@ -370,8 +330,7 @@ mod tests { #[test] fn found_rz_guppy() { - let epsilon = 1e-2; - let mut imported_hugr = &mut import_rz_only_guppy_circuit(); + let imported_hugr = &mut import_rz_only_guppy_circuit(); NormalizeGuppy::default() .simplify_cfgs(true) .remove_tuple_untuple(true) From 74ae91d51393977fd3a7411c988fb7db3936d618 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Thu, 11 Dec 2025 10:24:28 +0000 Subject: [PATCH 09/48] Working for simple guppy cases --- tket/src/passes/gridsynth.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index fd58e76ef..2c2bd24f0 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -205,22 +205,29 @@ fn add_gate_and_connect(hugr: &mut Hugr, prev_node: Node, op: hugr::ops::OpType, fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) { // getting node that gave qubit to Rz gate let mut prev_node = find_qubit_source(hugr, rz_node); - let parent = hugr.get_parent(rz_node).unwrap(); - let output_node = hugr.get_io(parent).unwrap()[1]; - // let dfg_output_node = find_sibling_output(hugr).unwrap(); + // find output port + let outputs: Vec<_> = hugr.node_outputs(rz_node).collect(); + let output_port = outputs[0]; + let (next_node, _) = hugr + .single_linked_input(rz_node, output_port) + .unwrap(); + + // we have now inferred what we need to know from the Rz node we are replacing and can remove it hugr.remove_node(rz_node); + // println!("in panicking function: {}", hugr.mermaid_string()); + // recursively adding next gate in gates to prev_node for gate in gates.chars() { if gate == 'H' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::H.into(), output_node); + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::H.into(), next_node); } else if gate == 'S' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::S.into(), output_node); + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::S.into(), next_node); } else if gate == 'T' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::T.into(), output_node); + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::T.into(), next_node); } else if gate == 'W' { // find output node and connect it to node for previous gate @@ -228,12 +235,14 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); // Assuming there were no outgoing ports to begin with when deciding port offset let src_port = ports[0]; - let ports: Vec<_> = hugr.node_inputs(output_node).collect(); + let ports: Vec<_> = hugr.node_inputs(next_node).collect(); let dst_port = ports[0]; - hugr.connect(prev_node, src_port, output_node, dst_port); + hugr.connect(prev_node, src_port, next_node, dst_port); break; // Ignoring global phases for now. } } + + println!("in panicking function: {}", hugr.mermaid_string()); hugr.validate().unwrap_or_else(|e| panic!("{e}")); } @@ -304,7 +313,6 @@ mod tests { let registry = std_reg(); let (_, imported_package) = read_described_envelope(reader, ®istry).unwrap(); let imported_hugr = imported_package.modules[0].clone(); - println!("Before: {}", imported_hugr.mermaid_string()); imported_hugr } From 0c14b7d2f331baf52a5b43958ff4c23595b0c927 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Thu, 11 Dec 2025 10:32:15 +0000 Subject: [PATCH 10/48] tidied up linting errors and commented out code --- tket/src/passes/gridsynth.rs | 39 ++---------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 2c2bd24f0..85759616b 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -1,4 +1,3 @@ -use hugr::NodeIndex; use hugr_core:: OutgoingPort; use rsgridsynth::config::config_from_theta_epsilon; use rsgridsynth::gridsynth::gridsynth_gates; @@ -19,7 +18,7 @@ use crate::passes::guppy::NormalizeGuppy; /// Find the FuncDefn node for the Rz gate. fn find_rz(hugr: &mut Hugr) -> Option { for node in hugr.nodes() { - let op_type = HugrView::get_optype(hugr, node); + let op_type = hugr.get_optype(node); if op_matches(op_type, TketOp::Rz) { return Some(node); } @@ -46,41 +45,6 @@ fn find_single_linked_output_by_index(hugr: &mut Hugr, node: Node, port_idx: usi prev_node_and_port } - // for node in hugr.nodes() { - // let op_type = HugrView::get_optype(hugr, node); - // if op_type.is_dfg() { - // let dfg_node = node; - // for node in hugr.descendants(dfg_node) { - // let op_type = HugrView::get_optype(hugr, node); - // if op_type.is_output() { - // return Some(node); - // } - // } - // } - // } - // None - -// fn search4angle(prev_node: Node) { -// for (pos, node) in hugr.input_neighbours(prev_node).with_position() { -// // let mut is_first_neighbour = true; // for checking if node is first neighbour -// let op_type = hugr.get_optype(node); -// if op_type.is_const() { -// break -// } -// else if pos == itertools::Position::Only { -// let first_neighbour = node; - -// } -// // if first neighbour -// else if pos == itertools::Position::First { -// let first_neighbour = node; -// } -// // else if is last element of neighbour -// else if ps == itertools::Position::Last { - -// } -// } -// } /// Find the constant node containing the angle to be inputted to the Rz gate. /// It is assumed that `hugr` has had the NormalizeGuppy passes applied to it @@ -283,6 +247,7 @@ mod tests { use super::*; + use hugr::NodeIndex; use hugr_core::std_extensions::std_reg; use crate::hugr::builder::Container; use crate::hugr::envelope::read_described_envelope; From c59dbc4be6a80e8d010c953120b0438612b44f4c Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Thu, 11 Dec 2025 14:53:27 +0000 Subject: [PATCH 11/48] Generalised to arbitry number of Rz gates --- tket/src/passes/gridsynth.rs | 98 +++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 29 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 85759616b..626e042ac 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -15,16 +15,26 @@ use hugr::std_extensions::arithmetic::float_types::ConstF64; use crate::passes::guppy::NormalizeGuppy; -/// Find the FuncDefn node for the Rz gate. -fn find_rz(hugr: &mut Hugr) -> Option { +/// Find the nodes for the Rz gates. +fn find_rzs(hugr: &mut Hugr) -> Option> { + let mut rz_nodes: Vec = Vec::new(); for node in hugr.nodes() { let op_type = hugr.get_optype(node); if op_matches(op_type, TketOp::Rz) { - return Some(node); + rz_nodes.push(node); + // return Some(node); } } + + // if there are rz_nodes: + if !(rz_nodes.is_empty()) { + return Some(rz_nodes); + } + // else return None None } + + // TO DO: extend this function to find all RZ gates fn find_linked_incoming_ports(hugr: &mut Hugr, node: Node, port_idx: usize) -> Vec<(Node, Port)> { @@ -82,8 +92,7 @@ fn find_angle_node(hugr: &mut Hugr, rz_node: Node) -> Node { } } -fn find_angle(hugr: &mut Hugr) -> f64 { - let rz_node = find_rz(hugr).unwrap(); +fn find_angle(hugr: &mut Hugr, rz_node: Node) -> f64 { let angle_node = find_angle_node(hugr, rz_node); let op_type = hugr.get_optype(angle_node); let angle_const = op_type.as_const().unwrap(); @@ -105,8 +114,8 @@ fn find_angle(hugr: &mut Hugr) -> f64 { angle } -fn apply_gridsynth(hugr: &mut Hugr, epsilon: f64) -> String { - let theta = find_angle(hugr); +fn apply_gridsynth(hugr: &mut Hugr, epsilon: f64, rz_node: Node) -> String { + let theta = find_angle(hugr, rz_node); // The following parameters could be made user-specifiable. For simplicity, I fix them, for now // let epsilon = 1e-1; // very low precision to allow easier visualisation for demo let seed = 1234; @@ -194,19 +203,16 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) prev_node = add_gate_and_connect(hugr, prev_node, TketOp::T.into(), next_node); } else if gate == 'W' { - // find output node and connect it to node for previous gate - - let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); - // Assuming there were no outgoing ports to begin with when deciding port offset - let src_port = ports[0]; - let ports: Vec<_> = hugr.node_inputs(next_node).collect(); - let dst_port = ports[0]; - hugr.connect(prev_node, src_port, next_node, dst_port); break; // Ignoring global phases for now. } } - - println!("in panicking function: {}", hugr.mermaid_string()); + let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); + // Assuming there were no outgoing ports to begin with when deciding port offset + let src_port = ports[0]; + let ports: Vec<_> = hugr.node_inputs(next_node).collect(); + let dst_port = ports[0]; + hugr.connect(prev_node, src_port, next_node, dst_port); + println!("Inside panicking function: {}", hugr.mermaid_string()); hugr.validate().unwrap_or_else(|e| panic!("{e}")); } @@ -222,9 +228,11 @@ pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) { .run(hugr) .unwrap(); - let rz_node = find_rz(hugr).unwrap(); - let gates = apply_gridsynth(hugr, epsilon); - replace_rz_with_gridsynth_output(hugr, rz_node, &gates); + let rz_nodes = find_rzs(hugr).unwrap(); + for node in rz_nodes { + let gates = apply_gridsynth(hugr, epsilon, node); + replace_rz_with_gridsynth_output(hugr, node, &gates); + } } // TO DO: make compatible with Guppy hugrs. Right now, it will only work for simple hugrs not like the @@ -267,13 +275,13 @@ mod tests { let mut circ = h.finish_hugr().unwrap(); //(rz.outputs()).unwrap().into(); println!("First mermaid string is: {}", circ.mermaid_string()); circ.validate().unwrap_or_else(|e| panic!("{e}")); - let rz_node = find_rz(&mut circ).unwrap(); + let rz_nodes = find_rzs(&mut circ).unwrap(); + let rz_node = rz_nodes[0]; (circ, rz_node) } - fn import_rz_only_guppy_circuit() -> Hugr { - // TODO: update the following path - let f = File::open("/home/kennycampbell/coding_projects/tket_gridsynth_ext/guppy_rz").unwrap(); + fn import_guppy(path: &'static str) -> Hugr { + let f = File::open(path).unwrap(); let reader = BufReader::new(f); let registry = std_reg(); let (_, imported_package) = read_described_envelope(reader, ®istry).unwrap(); @@ -281,6 +289,15 @@ mod tests { imported_hugr } + fn import_rz_only_guppy_circuit() -> Hugr { + // TODO: update the following path + import_guppy("/home/kennycampbell/coding_projects/tket_gridsynth_ext/guppy_rz") + } + + fn import_2rzs_guppy() -> Hugr { + import_guppy("/home/kennycampbell/coding_projects/tket_gridsynth_ext/guppy_2Rzs") + } + #[test] fn gridsynth_pass_successful() { @@ -296,8 +313,8 @@ mod tests { #[test] fn test_gridsynth_output_to_hugr() { let epsilon = 1e-3; - let (mut circ, _) = build_rz_only_circ(); - let gates = apply_gridsynth(&mut circ, epsilon); + let (mut circ, rz_node) = build_rz_only_circ(); + let gates = apply_gridsynth(&mut circ, epsilon, rz_node); gridsynth_output_to_hugr(&gates); } @@ -312,7 +329,8 @@ mod tests { .inline_dfgs(true) .run(imported_hugr) .unwrap(); - let rz_node = find_rz(imported_hugr).unwrap(); + let rz_nodes = find_rzs(imported_hugr).unwrap(); + let rz_node = rz_nodes[0]; assert_eq!(rz_node.index(), 17) } @@ -327,7 +345,8 @@ mod tests { .inline_dfgs(true) .run(imported_hugr) .unwrap(); - let rz_node = find_rz(imported_hugr).unwrap(); + let rz_nodes = find_rzs(imported_hugr).unwrap(); + let rz_node = rz_nodes[0]; let angle_node = find_angle_node(imported_hugr, rz_node); assert_eq!(angle_node.index(), 20); } @@ -343,7 +362,9 @@ mod tests { .inline_dfgs(true) .run(imported_hugr) .unwrap(); - let angle = find_angle(imported_hugr); + let rz_nodes = find_rzs(imported_hugr).unwrap(); + let rz_node = rz_nodes[0]; + let angle = find_angle(imported_hugr, rz_node); println!("angle is {}", angle); println!("hugr is {}", imported_hugr.mermaid_string()); } @@ -365,4 +386,23 @@ mod tests { apply_gridsynth_pass(&mut imported_hugr, epsilon); println!("after: {}", imported_hugr.mermaid_string()); } + + #[test] + fn test_2rzs_guppy_hugr() { + let epsilon = 1e-2; + let mut imported_hugr = &mut import_2rzs_guppy(); + println!("before: {}", imported_hugr.mermaid_string()); + NormalizeGuppy::default() + .simplify_cfgs(true) + .remove_tuple_untuple(true) + .constant_folding(true) + .remove_dead_funcs(true) + .inline_dfgs(true) + .run(imported_hugr) + .unwrap(); + // constant_fold_pass(imported_hugr.as_mut()); + // println!("after {}", imported_hugr.mermaid_string()); + apply_gridsynth_pass(&mut imported_hugr, epsilon); + println!("after: {}", imported_hugr.mermaid_string()); + } } From e2816cfc7668ef0097e6efafa984a49f7d160f89 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Mon, 15 Dec 2025 12:12:18 +0000 Subject: [PATCH 12/48] Added Python bindings --- tket-py/src/passes.rs | 2 ++ tket-py/src/passes/gridsynth.rs | 34 ++++++++++++++++++++++++++++++ tket-py/tket/_tket/passes.pyi | 12 +++++++++++ tket-py/tket/passes.py | 37 +++++++++++++++++++++++++++++++++ tket/src/passes/gridsynth.rs | 5 +---- 5 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 tket-py/src/passes/gridsynth.rs diff --git a/tket-py/src/passes.rs b/tket-py/src/passes.rs index e9461dbd3..5a2b08d15 100644 --- a/tket-py/src/passes.rs +++ b/tket-py/src/passes.rs @@ -2,6 +2,7 @@ pub mod chunks; pub mod tket1; +pub mod gridsynth; use std::{cmp::min, convert::TryInto, fs, num::NonZeroUsize, path::PathBuf}; @@ -29,6 +30,7 @@ pub fn module(py: Python<'_>) -> PyResult> { m.add_function(wrap_pyfunction!(normalize_guppy, &m)?)?; m.add_class::()?; m.add_function(wrap_pyfunction!(self::chunks::chunks, &m)?)?; + m.add_function(wrap_pyfunction!(self::gridsynth::gridsynth, &m)?)?; m.add_function(wrap_pyfunction!(self::tket1::tket1_pass, &m)?)?; m.add("PullForwardError", py.get_type::())?; m.add("TK1PassError", py.get_type::())?; diff --git a/tket-py/src/passes/gridsynth.rs b/tket-py/src/passes/gridsynth.rs new file mode 100644 index 000000000..22b5b64e4 --- /dev/null +++ b/tket-py/src/passes/gridsynth.rs @@ -0,0 +1,34 @@ +//! Bindings to allow users to access the gridsynth pass from Python + + +/// The definitions here should be reflected in the +/// `tket-py/tket/_tket/passes.pyi` type stubs file + +use pyo3::prelude::*; +use pyo3::types::PyFloat; +use tket::passes::gridsynth::apply_gridsynth_pass; +use crate::circuit::CircuitType; +use crate::utils::{create_py_exception, ConvertPyErr}; +use crate::circuit::{try_update_circ, try_with_circ}; + +// use tket::passes::gridsynth; + + +// TO DO: add bindings here similarly to tket1.rs +#[pyfunction] +pub fn gridsynth<'py>( + circ: &Bound<'py, PyAny>, + epsilon: f64 +) -> PyResult> { + let py = circ.py(); + + try_with_circ(circ, |mut circ: tket::Circuit, typ: CircuitType| { + apply_gridsynth_pass(circ.hugr_mut(), epsilon); + + let circ = typ.convert(py, circ)?; + PyResult::Ok(circ) + }) +} +// TO DO: change everything that refers to this as +// inplace to be not inplace as this implementation +// is not inplace \ No newline at end of file diff --git a/tket-py/tket/_tket/passes.pyi b/tket-py/tket/_tket/passes.pyi index 84a0521b7..ab3e8a302 100644 --- a/tket-py/tket/_tket/passes.pyi +++ b/tket-py/tket/_tket/passes.pyi @@ -5,6 +5,8 @@ from .optimiser import BadgerOptimiser from .circuit import Tk2Circuit from pytket._tket.circuit import Circuit +from hugr import Hugr + CircuitClass = TypeVar("CircuitClass", Circuit, Tk2Circuit) class CircuitChunks: @@ -103,3 +105,13 @@ def tket1_pass( circuit-like regions, and optimise them too. nested inside other subregions of the circuit. """ + +def gridsynth(hugr: Hugr, epsilon: float) -> Hugr: + """Runs a pass applying the gridsynth algorithm to all Rz gates in a HUGR, + which decomposes them into the Clifford + T basis. + + Parameters: + - hugr: the hugr to run the pass on. + - epsilon: the precision of the gridsynth decomposition + """ + diff --git a/tket-py/tket/passes.py b/tket-py/tket/passes.py index b0715c686..d3577aae2 100644 --- a/tket-py/tket/passes.py +++ b/tket-py/tket/passes.py @@ -31,6 +31,7 @@ tket1_pass, normalize_guppy, PullForwardError, + gridsynth ) __all__ = [ @@ -170,3 +171,39 @@ def _normalize(self, hugr: Hugr, inplace: bool) -> PassResult: ) new_hugr = Hugr.from_str(opt_program.to_str()) return PassResult.for_pass(self, hugr=new_hugr, inplace=inplace, result=None) + +@dataclass +class Gridsynth(ComposablePass): + epsilon: float + + """Apply the gridsynth algorithm to all Rz gates in the Hugr. + + This includes a NormalizeGuppy pass with all of the constituent passes applied + before applying gridsynth to standardise the + format. + + Parameters: + - epsilon: The allowable error tolerance. + """ + # TO DO: make the NormalizeGuppy pass optional, in case it is already run + # before Gridsynth. Need to warn users, at least in docs that if NormalizeGuppy + # is not run first then Gridsynth is likely to fail. Maybe issue the warning if + # the option to run NormalizeGuppy is set to False. The option would be specified + # as a field of the dataclass (would also need to add @dataclass decorator) + # like for NormalizeGuppy above + def run(self, hugr: Hugr, *, inplace: bool) -> PassResult: + # inplace option does nothing for now but I retain for consistency of + # API with other passes + return implement_pass_run( + self, + hugr=Hugr, + inplace=inplace, + inplace_call=self._apply_gridsynth_pass(hugr, self.epsilon) + ) + + def _apply_gridsynth_pass(self, hugr: Hugr, epsilon) -> PassResult: + # TO DO: think about whether to work with Tk2Circuits rather than the + # raw HUGR, like NormalizeGuppy. This may give further standardisation. + gridsynth(hugr, epsilon) + return PassResult.for_pass(self, hugr=hugr, inplace=True, result=None) + diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 626e042ac..18e942e3d 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -233,10 +233,7 @@ pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) { let gates = apply_gridsynth(hugr, epsilon, node); replace_rz_with_gridsynth_output(hugr, node, &gates); } -} - -// TO DO: make compatible with Guppy hugrs. Right now, it will only work for simple hugrs not like the -// ones that guppy produces +} // TO DO: change name of this function to gridsynth From 77c4e6de6c920eb1c4c99181e00564d1daeb9b5c Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Mon, 15 Dec 2025 14:56:17 +0000 Subject: [PATCH 13/48] Bindings no longer raising error in Python --- tket-py/test/test_pass.py | 3 ++- tket-py/tket/_tket/passes.pyi | 2 +- tket-py/tket/passes.py | 16 ++++++++-------- tket/src/passes/gridsynth.rs | 2 +- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/tket-py/test/test_pass.py b/tket-py/test/test_pass.py index 378550ada..bec4e2f54 100644 --- a/tket-py/test/test_pass.py +++ b/tket-py/test/test_pass.py @@ -7,7 +7,7 @@ greedy_depth_reduce, chunks, NormalizeGuppy, - normalize_guppy, + normalize_guppy ) from tket.circuit import Tk2Circuit @@ -216,3 +216,4 @@ def test_normalize_guppy(): c2 = Tk2Circuit(pytket_circ) normal_circ2 = normalize_guppy(c2) assert normal_circ2.circuit_cost(lambda op: int(op == TketOp.CX)) == 3 + \ No newline at end of file diff --git a/tket-py/tket/_tket/passes.pyi b/tket-py/tket/_tket/passes.pyi index ab3e8a302..7f3de95bf 100644 --- a/tket-py/tket/_tket/passes.pyi +++ b/tket-py/tket/_tket/passes.pyi @@ -106,7 +106,7 @@ def tket1_pass( nested inside other subregions of the circuit. """ -def gridsynth(hugr: Hugr, epsilon: float) -> Hugr: +def gridsynth(hugr: CircuitClass, epsilon: float) -> CircuitClass: """Runs a pass applying the gridsynth algorithm to all Rz gates in a HUGR, which decomposes them into the Clifford + T basis. diff --git a/tket-py/tket/passes.py b/tket-py/tket/passes.py index d3577aae2..e965c1456 100644 --- a/tket-py/tket/passes.py +++ b/tket-py/tket/passes.py @@ -191,19 +191,19 @@ class Gridsynth(ComposablePass): # the option to run NormalizeGuppy is set to False. The option would be specified # as a field of the dataclass (would also need to add @dataclass decorator) # like for NormalizeGuppy above - def run(self, hugr: Hugr, *, inplace: bool) -> PassResult: + def run(self, hugr: Hugr, *, inplace: bool = True) -> PassResult: # inplace option does nothing for now but I retain for consistency of # API with other passes return implement_pass_run( self, - hugr=Hugr, + hugr=hugr, inplace=inplace, - inplace_call=self._apply_gridsynth_pass(hugr, self.epsilon) + copy_call=lambda h: self._apply_gridsynth_pass(hugr, self.epsilon, inplace) ) - def _apply_gridsynth_pass(self, hugr: Hugr, epsilon) -> PassResult: - # TO DO: think about whether to work with Tk2Circuits rather than the - # raw HUGR, like NormalizeGuppy. This may give further standardisation. - gridsynth(hugr, epsilon) - return PassResult.for_pass(self, hugr=hugr, inplace=True, result=None) + def _apply_gridsynth_pass(self, hugr: Hugr, epsilon: float, inplace: bool) -> PassResult: + compiler_state: Tk2Circuit = Tk2Circuit.from_bytes(hugr.to_bytes()) + program = gridsynth(compiler_state, epsilon) + new_hugr = Hugr.from_str(program.to_str()) + return PassResult.for_pass(self, hugr=new_hugr, inplace=inplace, result=None) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 18e942e3d..20a464393 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -212,7 +212,7 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) let ports: Vec<_> = hugr.node_inputs(next_node).collect(); let dst_port = ports[0]; hugr.connect(prev_node, src_port, next_node, dst_port); - println!("Inside panicking function: {}", hugr.mermaid_string()); + // println!("Inside panicking function: {}", hugr.mermaid_string()); hugr.validate().unwrap_or_else(|e| panic!("{e}")); } From e21532e0062b5fa4ade72d5d4734a8f065e05ae9 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Mon, 15 Dec 2025 15:17:58 +0000 Subject: [PATCH 14/48] Added comment warning of rsgridsynth instability --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8b16facc5..2e93d95db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,7 +98,7 @@ cool_asserts = "2.0.4" zstd = "0.13.3" anyhow = "1.0.100" num-rational = "0.4.2" -rsgridsynth = { git = "https://github.com/qiskit-community/rsgridsynth.git"} +rsgridsynth = { git = "https://github.com/qiskit-community/rsgridsynth.git"} # not stable: (TO DO: fork?) [profile.release.package.tket-py] # Some configurations to reduce the size of tket wheels From 9072afa665953b9e7d166aa0dde25ac86fbfb831 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Mon, 15 Dec 2025 16:08:29 +0000 Subject: [PATCH 15/48] Updated rsgridsynth to new crates.io version --- Cargo.toml | 2 +- tket/src/passes/gridsynth.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2e93d95db..b28de2786 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,7 +98,7 @@ cool_asserts = "2.0.4" zstd = "0.13.3" anyhow = "1.0.100" num-rational = "0.4.2" -rsgridsynth = { git = "https://github.com/qiskit-community/rsgridsynth.git"} # not stable: (TO DO: fork?) +rsgridsynth = "0.2.0" [profile.release.package.tket-py] # Some configurations to reduce the size of tket wheels diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 20a464393..1c6b27641 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -120,7 +120,8 @@ fn apply_gridsynth(hugr: &mut Hugr, epsilon: f64, rz_node: Node) -> String { // let epsilon = 1e-1; // very low precision to allow easier visualisation for demo let seed = 1234; let verbose = false; - let mut gridsynth_config = config_from_theta_epsilon(theta, epsilon, seed, verbose); + let up_to_phase = false; + let mut gridsynth_config = config_from_theta_epsilon(theta, epsilon, seed, verbose, up_to_phase); let gates = gridsynth_gates(&mut gridsynth_config); let gates = gates.gates; gates From ae18726746cb693abe347513dab8dbc8e4f7b670 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Mon, 15 Dec 2025 16:45:00 +0000 Subject: [PATCH 16/48] Corrected formatting and linting errors --- tket-py/src/passes.rs | 4 +- tket-py/src/passes/gridsynth.rs | 32 +++--- tket-py/test/test_pass.py | 3 +- tket-py/tket/_tket/passes.pyi | 11 +-- tket-py/tket/passes.py | 25 ++--- tket/src/passes/gridsynth.rs | 166 +++++++++++++------------------- 6 files changed, 98 insertions(+), 143 deletions(-) diff --git a/tket-py/src/passes.rs b/tket-py/src/passes.rs index 5a2b08d15..37f7ca7d2 100644 --- a/tket-py/src/passes.rs +++ b/tket-py/src/passes.rs @@ -1,8 +1,8 @@ //! Passes for optimising circuits. pub mod chunks; -pub mod tket1; pub mod gridsynth; +pub mod tket1; use std::{cmp::min, convert::TryInto, fs, num::NonZeroUsize, path::PathBuf}; @@ -30,7 +30,7 @@ pub fn module(py: Python<'_>) -> PyResult> { m.add_function(wrap_pyfunction!(normalize_guppy, &m)?)?; m.add_class::()?; m.add_function(wrap_pyfunction!(self::chunks::chunks, &m)?)?; - m.add_function(wrap_pyfunction!(self::gridsynth::gridsynth, &m)?)?; + m.add_function(wrap_pyfunction!(self::gridsynth::gridsynth, &m)?)?; m.add_function(wrap_pyfunction!(self::tket1::tket1_pass, &m)?)?; m.add("PullForwardError", py.get_type::())?; m.add("TK1PassError", py.get_type::())?; diff --git a/tket-py/src/passes/gridsynth.rs b/tket-py/src/passes/gridsynth.rs index 22b5b64e4..50adc64bc 100644 --- a/tket-py/src/passes/gridsynth.rs +++ b/tket-py/src/passes/gridsynth.rs @@ -1,27 +1,17 @@ -//! Bindings to allow users to access the gridsynth pass from Python - - -/// The definitions here should be reflected in the -/// `tket-py/tket/_tket/passes.pyi` type stubs file - +//! Bindings to allow users to access the gridsynth pass from Python. +//! The definitions here should be reflected in the +//! `tket-py/tket/_tket/passes.pyi` type stubs file +use crate::circuit::CircuitType; +use crate::circuit::try_with_circ; use pyo3::prelude::*; -use pyo3::types::PyFloat; use tket::passes::gridsynth::apply_gridsynth_pass; -use crate::circuit::CircuitType; -use crate::utils::{create_py_exception, ConvertPyErr}; -use crate::circuit::{try_update_circ, try_with_circ}; - -// use tket::passes::gridsynth; - -// TO DO: add bindings here similarly to tket1.rs +/// Binding to a python function called gridsynth that runs the rust function called +/// apply_gridsynth pass behind the scenes #[pyfunction] -pub fn gridsynth<'py>( - circ: &Bound<'py, PyAny>, - epsilon: f64 -) -> PyResult> { +pub fn gridsynth<'py>(circ: &Bound<'py, PyAny>, epsilon: f64) -> PyResult> { let py = circ.py(); - + try_with_circ(circ, |mut circ: tket::Circuit, typ: CircuitType| { apply_gridsynth_pass(circ.hugr_mut(), epsilon); @@ -30,5 +20,5 @@ pub fn gridsynth<'py>( }) } // TO DO: change everything that refers to this as -// inplace to be not inplace as this implementation -// is not inplace \ No newline at end of file +// inplace to be not inplace as this implementation +// is not inplace diff --git a/tket-py/test/test_pass.py b/tket-py/test/test_pass.py index bec4e2f54..378550ada 100644 --- a/tket-py/test/test_pass.py +++ b/tket-py/test/test_pass.py @@ -7,7 +7,7 @@ greedy_depth_reduce, chunks, NormalizeGuppy, - normalize_guppy + normalize_guppy, ) from tket.circuit import Tk2Circuit @@ -216,4 +216,3 @@ def test_normalize_guppy(): c2 = Tk2Circuit(pytket_circ) normal_circ2 = normalize_guppy(c2) assert normal_circ2.circuit_cost(lambda op: int(op == TketOp.CX)) == 3 - \ No newline at end of file diff --git a/tket-py/tket/_tket/passes.pyi b/tket-py/tket/_tket/passes.pyi index 7f3de95bf..a59929518 100644 --- a/tket-py/tket/_tket/passes.pyi +++ b/tket-py/tket/_tket/passes.pyi @@ -5,8 +5,6 @@ from .optimiser import BadgerOptimiser from .circuit import Tk2Circuit from pytket._tket.circuit import Circuit -from hugr import Hugr - CircuitClass = TypeVar("CircuitClass", Circuit, Tk2Circuit) class CircuitChunks: @@ -108,10 +106,9 @@ def tket1_pass( def gridsynth(hugr: CircuitClass, epsilon: float) -> CircuitClass: """Runs a pass applying the gridsynth algorithm to all Rz gates in a HUGR, - which decomposes them into the Clifford + T basis. + which decomposes them into the Clifford + T basis. - Parameters: - - hugr: the hugr to run the pass on. - - epsilon: the precision of the gridsynth decomposition + Parameters: + - hugr: the hugr to run the pass on. + - epsilon: the precision of the gridsynth decomposition """ - diff --git a/tket-py/tket/passes.py b/tket-py/tket/passes.py index e965c1456..3c376e7de 100644 --- a/tket-py/tket/passes.py +++ b/tket-py/tket/passes.py @@ -31,7 +31,7 @@ tket1_pass, normalize_guppy, PullForwardError, - gridsynth + gridsynth, ) __all__ = [ @@ -172,38 +172,41 @@ def _normalize(self, hugr: Hugr, inplace: bool) -> PassResult: new_hugr = Hugr.from_str(opt_program.to_str()) return PassResult.for_pass(self, hugr=new_hugr, inplace=inplace, result=None) + @dataclass class Gridsynth(ComposablePass): epsilon: float - """Apply the gridsynth algorithm to all Rz gates in the Hugr. - + """Apply the gridsynth algorithm to all Rz gates in the Hugr. + This includes a NormalizeGuppy pass with all of the constituent passes applied before applying gridsynth to standardise the format. - + Parameters: - epsilon: The allowable error tolerance. """ - # TO DO: make the NormalizeGuppy pass optional, in case it is already run + + # TO DO: make the NormalizeGuppy pass optional, in case it is already run # before Gridsynth. Need to warn users, at least in docs that if NormalizeGuppy - # is not run first then Gridsynth is likely to fail. Maybe issue the warning if + # is not run first then Gridsynth is likely to fail. Maybe issue the warning if # the option to run NormalizeGuppy is set to False. The option would be specified # as a field of the dataclass (would also need to add @dataclass decorator) # like for NormalizeGuppy above def run(self, hugr: Hugr, *, inplace: bool = True) -> PassResult: - # inplace option does nothing for now but I retain for consistency of + # inplace option does nothing for now but I retain for consistency of # API with other passes return implement_pass_run( self, hugr=hugr, inplace=inplace, - copy_call=lambda h: self._apply_gridsynth_pass(hugr, self.epsilon, inplace) + copy_call=lambda h: self._apply_gridsynth_pass(hugr, self.epsilon, inplace), ) - - def _apply_gridsynth_pass(self, hugr: Hugr, epsilon: float, inplace: bool) -> PassResult: + + def _apply_gridsynth_pass( + self, hugr: Hugr, epsilon: float, inplace: bool + ) -> PassResult: compiler_state: Tk2Circuit = Tk2Circuit.from_bytes(hugr.to_bytes()) program = gridsynth(compiler_state, epsilon) new_hugr = Hugr.from_str(program.to_str()) return PassResult.for_pass(self, hugr=new_hugr, inplace=inplace, result=None) - diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 1c6b27641..2a87efad2 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -1,23 +1,21 @@ -use hugr_core:: OutgoingPort; -use rsgridsynth::config::config_from_theta_epsilon; -use rsgridsynth::gridsynth::gridsynth_gates; +//! A pass that applies the gridsynth algorithm to all Rz gates in a HUGR. + use crate::extension::rotation::ConstRotation; -use crate::{Hugr, hugr, op_matches}; -use crate::hugr::builder::{DFGBuilder, Dataflow, HugrBuilder}; -use crate::hugr::extension::prelude::{qb_t}; -use crate::hugr::HugrView; use crate::hugr::hugr::hugrmut::HugrMut; +use crate::hugr::HugrView; use crate::hugr::{Node, Port}; -use crate::hugr::types::Signature; +use crate::passes::guppy::NormalizeGuppy; use crate::TketOp; +use crate::{hugr, op_matches, Hugr}; use hugr::algorithms::ComposablePass; use hugr::std_extensions::arithmetic::float_types::ConstF64; -use crate::passes::guppy::NormalizeGuppy; - +use hugr_core::OutgoingPort; +use rsgridsynth::config::config_from_theta_epsilon; +use rsgridsynth::gridsynth::gridsynth_gates; /// Find the nodes for the Rz gates. fn find_rzs(hugr: &mut Hugr) -> Option> { - let mut rz_nodes: Vec = Vec::new(); + let mut rz_nodes: Vec = Vec::new(); for node in hugr.nodes() { let op_type = hugr.get_optype(node); if op_matches(op_type, TketOp::Rz) { @@ -34,31 +32,33 @@ fn find_rzs(hugr: &mut Hugr) -> Option> { None } - // TO DO: extend this function to find all RZ gates fn find_linked_incoming_ports(hugr: &mut Hugr, node: Node, port_idx: usize) -> Vec<(Node, Port)> { let ports = hugr.node_inputs(node); let collected_ports: Vec<_> = ports.collect(); - let linked_ports = hugr. - linked_ports(node, collected_ports[port_idx]); + let linked_ports = hugr.linked_ports(node, collected_ports[port_idx]); let linked_ports: Vec<(Node, Port)> = linked_ports.collect(); linked_ports } /// find the output port and node linked to the input specified by `port_idz` for `node` -fn find_single_linked_output_by_index(hugr: &mut Hugr, node: Node, port_idx: usize) -> (Node, OutgoingPort) { +fn find_single_linked_output_by_index( + hugr: &mut Hugr, + node: Node, + port_idx: usize, +) -> (Node, OutgoingPort) { let ports = hugr.node_inputs(node); let collected_ports: Vec<_> = ports.collect(); - let prev_node_and_port = hugr. - single_linked_output(node, collected_ports[port_idx]).unwrap(); - prev_node_and_port -} + hugr + .single_linked_output(node, collected_ports[port_idx]) + .unwrap() +} /// Find the constant node containing the angle to be inputted to the Rz gate. -/// It is assumed that `hugr` has had the NormalizeGuppy passes applied to it -/// prior to being applied. This function also cleans up behind itself removing +/// It is assumed that `hugr` has had the NormalizeGuppy passes applied to it +/// prior to being applied. This function also cleans up behind itself removing /// everything on the path to the `angle_node` but not the `angle_node` itself, /// which is still needed. fn find_angle_node(hugr: &mut Hugr, rz_node: Node) -> Node { @@ -88,7 +88,6 @@ fn find_angle_node(hugr: &mut Hugr, rz_node: Node) -> Node { prev_node = current_node; ii += 1; - } } @@ -100,15 +99,15 @@ fn find_angle(hugr: &mut Hugr, rz_node: Node) -> f64 { // handling likely angle formats. Panic if angle is not one of the anticipated formats let angle = if let Some(rot) = angle_val.get_custom_value::() { - rot.to_radians() + rot.to_radians() } else if let Some(fl) = angle_val.get_custom_value::() { - let half_turns = fl.value(); - ConstRotation::new(half_turns).unwrap().to_radians() + let half_turns = fl.value(); + ConstRotation::new(half_turns).unwrap().to_radians() } else { panic!("Angle not specified as ConstRotation or ConstF64") }; - - // we now have what we need to know from the angle node and can remove it from the hugr + + // we now have what we need to know from the angle node and can remove it from the hugr hugr.remove_node(angle_node); angle @@ -121,60 +120,38 @@ fn apply_gridsynth(hugr: &mut Hugr, epsilon: f64, rz_node: Node) -> String { let seed = 1234; let verbose = false; let up_to_phase = false; - let mut gridsynth_config = config_from_theta_epsilon(theta, epsilon, seed, verbose, up_to_phase); + let mut gridsynth_config = + config_from_theta_epsilon(theta, epsilon, seed, verbose, up_to_phase); let gates = gridsynth_gates(&mut gridsynth_config); - let gates = gates.gates; - gates -} - -fn gridsynth_output_to_hugr(gates: &str) -> Hugr { - let qb_row = vec![qb_t(); 1]; // TO CHECK: will it cause issues to insert new qubit wire? - let mut h = DFGBuilder::new(Signature::new(qb_row.clone(), qb_row)).unwrap(); - - let mut prev_op = h.input(); - for gate in gates.chars() { - if gate == 'H' { - prev_op = h.add_dataflow_op(TketOp::H, prev_op.outputs()).unwrap(); - } - else if gate == 'S' { - prev_op = h.add_dataflow_op(TketOp::S, prev_op.outputs()).unwrap(); - } - else if gate == 'T' { - prev_op = h.add_dataflow_op(TketOp::T, prev_op.outputs()).unwrap(); - } - else if gate == 'W' { - break; // Ignoring global phases for now. - } - } - h.set_outputs(prev_op.outputs()).unwrap(); - let hugr = h.finish_hugr().unwrap(); - hugr.validate().unwrap_or_else(|e| panic!("{e}")); - hugr + gates.gates } - /// get previous node that provided qubit to Rz gate fn find_qubit_source(hugr: &mut Hugr, rz_node: Node) -> Node { let linked_ports = find_linked_incoming_ports(hugr, rz_node, 0); - let prev_node = linked_ports[0].0; - prev_node + + linked_ports[0].0 } -/// Add a gridsynth gate to some previous node, which may or may not be a gridsynth gate, +/// Add a gridsynth gate to some previous node, which may or may not be a gridsynth gate, /// and connect -fn add_gate_and_connect(hugr: &mut Hugr, prev_node: Node, op: hugr::ops::OpType, output_node: Node) -> Node { - let current_node = hugr.add_node_after(output_node, op); - let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); +fn add_gate_and_connect( + hugr: &mut Hugr, + prev_node: Node, + op: hugr::ops::OpType, + output_node: Node, +) -> Node { + let current_node = hugr.add_node_after(output_node, op); + let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); // Assuming there were no outgoing ports to begin with when deciding port offset let src_port = ports[0]; - let ports: Vec<_> = hugr.node_inputs(current_node).collect(); + let ports: Vec<_> = hugr.node_inputs(current_node).collect(); let dst_port = ports[0]; hugr.connect(prev_node, src_port, current_node, dst_port); - let prev_node = current_node; - prev_node -} + current_node +} fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) { // getting node that gave qubit to Rz gate @@ -183,9 +160,7 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) // find output port let outputs: Vec<_> = hugr.node_outputs(rz_node).collect(); let output_port = outputs[0]; - let (next_node, _) = hugr - .single_linked_input(rz_node, output_port) - .unwrap(); + let (next_node, _) = hugr.single_linked_input(rz_node, output_port).unwrap(); // we have now inferred what we need to know from the Rz node we are replacing and can remove it hugr.remove_node(rz_node); @@ -196,26 +171,23 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) for gate in gates.chars() { if gate == 'H' { prev_node = add_gate_and_connect(hugr, prev_node, TketOp::H.into(), next_node); - } - else if gate == 'S' { + } else if gate == 'S' { prev_node = add_gate_and_connect(hugr, prev_node, TketOp::S.into(), next_node); - } - else if gate == 'T' { + } else if gate == 'T' { prev_node = add_gate_and_connect(hugr, prev_node, TketOp::T.into(), next_node); - } - else if gate == 'W' { + } else if gate == 'W' { break; // Ignoring global phases for now. } } - let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); + let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); // Assuming there were no outgoing ports to begin with when deciding port offset let src_port = ports[0]; - let ports: Vec<_> = hugr.node_inputs(next_node).collect(); + let ports: Vec<_> = hugr.node_inputs(next_node).collect(); let dst_port = ports[0]; hugr.connect(prev_node, src_port, next_node, dst_port); // println!("Inside panicking function: {}", hugr.mermaid_string()); hugr.validate().unwrap_or_else(|e| panic!("{e}")); -} +} /// Replace an Rz gate with the corresponding gates outputted by gridsynth pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) { @@ -236,8 +208,6 @@ pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) { } } // TO DO: change name of this function to gridsynth - - /// Example error. #[derive(Debug, derive_more::Display, derive_more::Error)] #[display("Example error: {message}")] @@ -253,12 +223,15 @@ mod tests { use super::*; - use hugr::NodeIndex; - use hugr_core::std_extensions::std_reg; + use crate::extension::rotation::ConstRotation; use crate::hugr::builder::Container; use crate::hugr::envelope::read_described_envelope; use crate::hugr::ops::Value; - use crate::extension::rotation::ConstRotation; + use hugr::NodeIndex; + use hugr_core::std_extensions::std_reg; + use crate::hugr::types::Signature; + use crate::hugr::builder::{DFGBuilder, Dataflow, HugrBuilder}; + use crate::hugr::extension::prelude::qb_t; fn build_rz_only_circ() -> (Hugr, Node) { let theta = 0.64; @@ -266,7 +239,9 @@ mod tests { let mut h = DFGBuilder::new(Signature::new(qb_row.clone(), qb_row)).unwrap(); let [q_in] = h.input_wires_arr(); - let constant = h.add_constant(Value::extension(ConstRotation::from_radians(theta).unwrap())); + let constant = h.add_constant(Value::extension( + ConstRotation::from_radians(theta).unwrap(), + )); let loaded_const = h.load_const(&constant); let rz = h.add_dataflow_op(TketOp::Rz, [q_in, loaded_const]).unwrap(); let _ = h.set_outputs(rz.outputs()); @@ -283,8 +258,8 @@ mod tests { let reader = BufReader::new(f); let registry = std_reg(); let (_, imported_package) = read_described_envelope(reader, ®istry).unwrap(); - let imported_hugr = imported_package.modules[0].clone(); - imported_hugr + + imported_package.modules[0].clone() } fn import_rz_only_guppy_circuit() -> Hugr { @@ -296,26 +271,17 @@ mod tests { import_guppy("/home/kennycampbell/coding_projects/tket_gridsynth_ext/guppy_2Rzs") } - #[test] fn gridsynth_pass_successful() { // This test is just to check if a panic occurs let (mut circ, _) = build_rz_only_circ(); let epsilon: f64 = 1e-3; // let gates = apply_gridsynth(&mut circ, epsilon); - // println!("{}", &gates); + // println!("{}", &gates); apply_gridsynth_pass(&mut circ, epsilon); // println!("{}", circ.mermaid_string()); } - #[test] - fn test_gridsynth_output_to_hugr() { - let epsilon = 1e-3; - let (mut circ, rz_node) = build_rz_only_circ(); - let gates = apply_gridsynth(&mut circ, epsilon, rz_node); - gridsynth_output_to_hugr(&gates); - } - #[test] fn found_rz_guppy() { let imported_hugr = &mut import_rz_only_guppy_circuit(); @@ -370,7 +336,7 @@ mod tests { #[test] fn test_with_guppy_hugr() { let epsilon = 1e-2; - let mut imported_hugr = &mut import_rz_only_guppy_circuit(); + let imported_hugr = &mut import_rz_only_guppy_circuit(); NormalizeGuppy::default() .simplify_cfgs(true) .remove_tuple_untuple(true) @@ -381,14 +347,14 @@ mod tests { .unwrap(); // constant_fold_pass(imported_hugr.as_mut()); // println!("after {}", imported_hugr.mermaid_string()); - apply_gridsynth_pass(&mut imported_hugr, epsilon); + apply_gridsynth_pass(imported_hugr, epsilon); println!("after: {}", imported_hugr.mermaid_string()); } #[test] fn test_2rzs_guppy_hugr() { let epsilon = 1e-2; - let mut imported_hugr = &mut import_2rzs_guppy(); + let imported_hugr = &mut import_2rzs_guppy(); println!("before: {}", imported_hugr.mermaid_string()); NormalizeGuppy::default() .simplify_cfgs(true) @@ -400,7 +366,7 @@ mod tests { .unwrap(); // constant_fold_pass(imported_hugr.as_mut()); // println!("after {}", imported_hugr.mermaid_string()); - apply_gridsynth_pass(&mut imported_hugr, epsilon); + apply_gridsynth_pass(imported_hugr, epsilon); println!("after: {}", imported_hugr.mermaid_string()); } } From 14fce82f651cfbccdc1f568d70adf30718410f9c Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Mon, 15 Dec 2025 16:54:59 +0000 Subject: [PATCH 17/48] just check now passin --- tket-py/src/passes/gridsynth.rs | 4 ++-- tket/src/passes/gridsynth.rs | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tket-py/src/passes/gridsynth.rs b/tket-py/src/passes/gridsynth.rs index 50adc64bc..b44ed6112 100644 --- a/tket-py/src/passes/gridsynth.rs +++ b/tket-py/src/passes/gridsynth.rs @@ -1,8 +1,8 @@ //! Bindings to allow users to access the gridsynth pass from Python. -//! The definitions here should be reflected in the +//! The definitions here should be reflected in the //! `tket-py/tket/_tket/passes.pyi` type stubs file -use crate::circuit::CircuitType; use crate::circuit::try_with_circ; +use crate::circuit::CircuitType; use pyo3::prelude::*; use tket::passes::gridsynth::apply_gridsynth_pass; diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 2a87efad2..820eacf8b 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -51,8 +51,7 @@ fn find_single_linked_output_by_index( let ports = hugr.node_inputs(node); let collected_ports: Vec<_> = ports.collect(); - hugr - .single_linked_output(node, collected_ports[port_idx]) + hugr.single_linked_output(node, collected_ports[port_idx]) .unwrap() } @@ -224,14 +223,13 @@ mod tests { use super::*; use crate::extension::rotation::ConstRotation; - use crate::hugr::builder::Container; + use crate::hugr::builder::{Container, DFGBuilder, Dataflow, HugrBuilder}; use crate::hugr::envelope::read_described_envelope; + use crate::hugr::extension::prelude::qb_t; use crate::hugr::ops::Value; + use crate::hugr::types::Signature; use hugr::NodeIndex; use hugr_core::std_extensions::std_reg; - use crate::hugr::types::Signature; - use crate::hugr::builder::{DFGBuilder, Dataflow, HugrBuilder}; - use crate::hugr::extension::prelude::qb_t; fn build_rz_only_circ() -> (Hugr, Node) { let theta = 0.64; From 9fef0b6428799aef6ffad2f11502dfadced47855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 10:29:29 +0000 Subject: [PATCH 18/48] feat! Bump hugr to 0.25.0 --- Cargo.lock | 98 +++++++++++++++++++++++------------------------------- Cargo.toml | 18 +++++----- 2 files changed, 51 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d240e1346..499452d9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1088,8 +1088,7 @@ dependencies = [ [[package]] name = "hugr" version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d8b180fc27111bc631352b8516a281703430d96b4e0c4bedecb00585bb7bbb2" +source = "git+https://github.com/quantinuum/hugr?rev=5415abebf35be4af4e5bac5c7fe54381aea55a3e#5415abebf35be4af4e5bac5c7fe54381aea55a3e" dependencies = [ "hugr-core", "hugr-llvm", @@ -1100,8 +1099,7 @@ dependencies = [ [[package]] name = "hugr-cli" version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a63e1e7d6f798e9bd032fd616854b4294d680056088a386d8a9a6c00b4291c" +source = "git+https://github.com/quantinuum/hugr?rev=5415abebf35be4af4e5bac5c7fe54381aea55a3e#5415abebf35be4af4e5bac5c7fe54381aea55a3e" dependencies = [ "anyhow", "clap", @@ -1109,7 +1107,7 @@ dependencies = [ "clio", "derive_more 2.1.0", "hugr", - "schemars 1.0.5", + "schemars 1.1.0", "serde", "serde_json", "tabled", @@ -1121,8 +1119,7 @@ dependencies = [ [[package]] name = "hugr-core" version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cde86f402bdea148e74c72a951354839dd1fb1f703fe620b4ef4d471a7d5978" +source = "git+https://github.com/quantinuum/hugr?rev=5415abebf35be4af4e5bac5c7fe54381aea55a3e#5415abebf35be4af4e5bac5c7fe54381aea55a3e" dependencies = [ "base64", "cgmath", @@ -1141,7 +1138,7 @@ dependencies = [ "regex", "relrc", "rustc-hash 2.1.1", - "schemars 1.0.5", + "schemars 1.1.0", "semver", "serde", "serde_json", @@ -1159,8 +1156,7 @@ dependencies = [ [[package]] name = "hugr-llvm" version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55104ec359dcf7c608a903dcb69be0297fcdda812c37bce18ee13b0ca3a0930" +source = "git+https://github.com/quantinuum/hugr?rev=5415abebf35be4af4e5bac5c7fe54381aea55a3e#5415abebf35be4af4e5bac5c7fe54381aea55a3e" dependencies = [ "anyhow", "cc", @@ -1179,8 +1175,7 @@ dependencies = [ [[package]] name = "hugr-model" version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2db0fbf9bf9e6f5828b905403c3c1e3b3b4e27520e92930a16915abbef60909b" +source = "git+https://github.com/quantinuum/hugr?rev=5415abebf35be4af4e5bac5c7fe54381aea55a3e#5415abebf35be4af4e5bac5c7fe54381aea55a3e" dependencies = [ "base64", "bumpalo", @@ -1201,8 +1196,7 @@ dependencies = [ [[package]] name = "hugr-passes" version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e170464e6c94176cd39099f52bac95552bf360b971959cd8a4a27d76e645ab9" +source = "git+https://github.com/quantinuum/hugr?rev=5415abebf35be4af4e5bac5c7fe54381aea55a3e#5415abebf35be4af4e5bac5c7fe54381aea55a3e" dependencies = [ "ascent", "derive_more 2.1.0", @@ -1285,23 +1279,22 @@ dependencies = [ [[package]] name = "inkwell" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67349bd7578d4afebbe15eaa642a80b884e8623db74b1716611b131feb1deef" +checksum = "39457e8611219cf690f862a470575f5c06862910d03ea3c3b187ad7abc44b4e2" dependencies = [ - "either", "inkwell_internals", "libc", "llvm-sys", "once_cell", - "thiserror 1.0.69", + "thiserror 2.0.17", ] [[package]] name = "inkwell_internals" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f365c8de536236cfdebd0ba2130de22acefed18b1fb99c32783b3840aec5fb46" +checksum = "ad9a7dd586b00f2b20e0b9ae3c6faa351fbfd56d15d63bbce35b13bece682eda" dependencies = [ "proc-macro2", "quote", @@ -1629,9 +1622,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pastey" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" +checksum = "57d6c094ee800037dff99e02cab0eaf3142826586742a270ab3d7a62656bd27a" [[package]] name = "peak_alloc" @@ -1883,9 +1876,9 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.26.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383" +checksum = "ab53c047fcd1a1d2a8820fe84f05d6be69e9526be40cb03b73f86b6b03e6d87d" dependencies = [ "anyhow", "indoc", @@ -1893,7 +1886,7 @@ dependencies = [ "memoffset", "once_cell", "portable-atomic", - "pyo3-build-config 0.26.0", + "pyo3-build-config", "pyo3-ffi", "pyo3-macros", "unindent", @@ -1901,37 +1894,28 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f" -dependencies = [ - "target-lexicon", -] - -[[package]] -name = "pyo3-build-config" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f77d387774f6f6eec64a004eac0ed525aab7fa1966d94b42f743797b3e395afb" +checksum = "b455933107de8642b4487ed26d912c2d899dec6114884214a0b3bb3be9261ea6" dependencies = [ "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.26.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105" +checksum = "1c85c9cbfaddf651b1221594209aed57e9e5cff63c4d11d1feead529b872a089" dependencies = [ "libc", - "pyo3-build-config 0.26.0", + "pyo3-build-config", ] [[package]] name = "pyo3-macros" -version = "0.26.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded" +checksum = "0a5b10c9bf9888125d917fb4d2ca2d25c8df94c7ab5a52e13313a07e050a3b02" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -1941,22 +1925,22 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.26.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf" +checksum = "03b51720d314836e53327f5871d4c0cfb4fb37cc2c4a11cc71907a86342c40f9" dependencies = [ "heck", "proc-macro2", - "pyo3-build-config 0.26.0", + "pyo3-build-config", "quote", "syn 2.0.108", ] [[package]] name = "pythonize" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11e06e4cff9be2bbf2bddf28a486ae619172ea57e79787f856572878c62dcfe2" +checksum = "a3a8f29db331e28c332c63496cfcbb822aca3d7320bc08b655d7fd0c29c50ede" dependencies = [ "pyo3", "serde", @@ -2222,9 +2206,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.0.5" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1317c3bf3e7df961da95b0a56a172a02abead31276215a0497241a7624b487ce" +checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" dependencies = [ "dyn-clone", "ref-cast", @@ -2235,9 +2219,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "1.0.5" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f760a6150d45dd66ec044983c124595ae76912e77ed0b44124cb3e415cce5d9" +checksum = "301858a4023d78debd2353c7426dc486001bddc91ae31a76fb1f55132f7e2633" dependencies = [ "proc-macro2", "quote", @@ -2260,7 +2244,7 @@ dependencies = [ "insta", "itertools 0.14.0", "pyo3", - "pyo3-build-config 0.27.1", + "pyo3-build-config", "rstest", "serde", "serde_json", @@ -2356,7 +2340,7 @@ dependencies = [ "indexmap 1.9.3", "indexmap 2.12.1", "schemars 0.9.0", - "schemars 1.0.5", + "schemars 1.1.0", "serde_core", "serde_json", "serde_with_macros", @@ -2709,9 +2693,9 @@ dependencies = [ [[package]] name = "tket-json-rs" -version = "0.7.7" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c424855b86bde6c2d1651241abf829f1bfcd8e5428356576ac11bd825357bc" +checksum = "aea5374e5ef784cd4825cfcd7cfaf4c8a6a39a2da6129b12181aa0c9234f9678" dependencies = [ "derive_more 2.1.0", "pyo3", @@ -3002,13 +2986,13 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ "getrandom", "js-sys", - "serde", + "serde_core", "wasm-bindgen", ] diff --git a/Cargo.toml b/Cargo.toml index 0510d7b3d..68bcecc54 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,11 +40,11 @@ large_enum_variant = "allow" [patch.crates-io] # Uncomment to use unreleased versions of hugr -# hugr = { git = "https://github.com/quantinuum/hugr", "branch" = "ts/ba-copy-discard" } -# hugr-core = { git = "https://github.com/quantinuum/hugr", "branch" = "ts/ba-copy-discard" } -# hugr-cli = { git = "https://github.com/quantinuum/hugr", "branch" = "ts/ba-copy-discard" } -# hugr-passes = { git = "https://github.com/quantinuum/hugr", "branch" = "ts/ba-copy-discard" } -# hugr-llvm = { git = "https://github.com/quantinuum/hugr", "branch" = "ts/ba-copy-discard" } +hugr = { git = "https://github.com/quantinuum/hugr", "rev" = "5415abebf35be4af4e5bac5c7fe54381aea55a3e" } +hugr-core = { git = "https://github.com/quantinuum/hugr", "rev" = "5415abebf35be4af4e5bac5c7fe54381aea55a3e" } +hugr-cli = { git = "https://github.com/quantinuum/hugr", "rev" = "5415abebf35be4af4e5bac5c7fe54381aea55a3e" } +hugr-passes = { git = "https://github.com/quantinuum/hugr", "rev" = "5415abebf35be4af4e5bac5c7fe54381aea55a3e" } +hugr-llvm = { git = "https://github.com/quantinuum/hugr", "rev" = "5415abebf35be4af4e5bac5c7fe54381aea55a3e" } # portgraph = { git = "https://github.com/quantinuum/portgraph", rev = "68b96ac737e0c285d8c543b2d74a7aa80a18202c" } [workspace.dependencies] @@ -54,15 +54,17 @@ hugr = "0.24.3" hugr-core = "0.24.3" hugr-cli = "0.24.3" portgraph = "0.15.3" -pyo3 = ">= 0.23.4, < 0.27" -pyo3-build-config = ">= 0.23.4, < 0.28" +# There can only be one `pyo3` dependency in the whole workspace, so we use a +# loose version constraint to prevent breaking changes in dependent crates where possible. +pyo3 = ">= 0.27.2, < 0.28" +pyo3-build-config = ">= 0.27.2, < 0.28" bindgen = "0.72" cbindgen = "0.29" cc = "1.2.49" conan2 = "0.1.8" itertools = "0.14.0" -tket-json-rs = "0.7.7" +tket-json-rs = "0.8.0" portmatching = "0.3.3" bytemuck = "1.24.0" cgmath = "0.18.0" From 4060c73a1f2b61be0de8c16e13177665d56fe2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 10:29:49 +0000 Subject: [PATCH 19/48] drive-by: Fix justfile setup --- justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/justfile b/justfile index 838701907..be1481a5b 100644 --- a/justfile +++ b/justfile @@ -16,7 +16,7 @@ _check_default_conan_profile: # Prepare the environment for development, installing all the dependencies and # setting up the pre-commit hooks. -setup: _check_default_conan_profile _check_nextest_installed +setup: && _check_default_conan_profile _check_nextest_installed uv tool install conan uv sync [[ -n "${TKET_JUST_INHIBIT_GIT_HOOKS:-}" ]] || uv run pre-commit install -t pre-commit From 9ae79613dfbbe12a6459761df3c29c8e60937d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 10:30:12 +0000 Subject: [PATCH 20/48] Update envelope / read errors --- tket/src/serialize.rs | 16 ++++----- tket/src/serialize/pytket/decoder/subgraph.rs | 3 +- tket/src/serialize/pytket/error.rs | 35 ++++++++++++++----- tket/src/serialize/pytket/opaque/payload.rs | 22 ++++-------- 4 files changed, 43 insertions(+), 33 deletions(-) diff --git a/tket/src/serialize.rs b/tket/src/serialize.rs index 8094e5dcf..2e24bff5d 100644 --- a/tket/src/serialize.rs +++ b/tket/src/serialize.rs @@ -3,7 +3,7 @@ //! See [`crate::serialize::pytket`] for serialization to and from the legacy pytket format. pub mod pytket; -pub use hugr::envelope::{EnvelopeConfig, EnvelopeError}; +pub use hugr::envelope::EnvelopeConfig; use hugr::hugr::hugrmut::HugrMut; use std::io; @@ -29,22 +29,22 @@ impl Circuit { &self, writer: impl io::Write, config: EnvelopeConfig, - ) -> Result<(), EnvelopeError> { - let pkg = self.wrap_package()?; + ) -> Result<(), hugr::envelope::WriteError> { + let pkg = self.wrap_package(); pkg.store(writer, config)?; Ok(()) } /// Store the circuit as a String in HUGR envelope format. - pub fn store_str(&self, config: EnvelopeConfig) -> Result { - let pkg = self.wrap_package()?; + pub fn store_str(&self, config: EnvelopeConfig) -> Result { + let pkg = self.wrap_package(); pkg.store_str(config) } /// Wrap the circuit in a package. - fn wrap_package(&self) -> Result { + fn wrap_package(&self) -> Package { let hugr = Circuit::to_owned(self).into_hugr(); - Ok(Package::from_hugr(hugr)) + Package::from_hugr(hugr) } } @@ -163,7 +163,7 @@ pub enum CircuitLoadError { CircuitLoadError(CircuitError), /// Error loading an envelope. #[from] - EnvelopeError(EnvelopeError), + EnvelopeError(hugr::envelope::ReadError), /// Error validating the loaded circuit. #[from] ValidationError(ValidationError), diff --git a/tket/src/serialize/pytket/decoder/subgraph.rs b/tket/src/serialize/pytket/decoder/subgraph.rs index 99b6a3d25..677323071 100644 --- a/tket/src/serialize/pytket/decoder/subgraph.rs +++ b/tket/src/serialize/pytket/decoder/subgraph.rs @@ -14,6 +14,7 @@ use crate::extension::rotation::rotation_type; use crate::serialize::pytket::decoder::{ DecodeStatus, FoundWire, LoadedParameter, PytketDecoderContext, TrackedBit, TrackedQubit, }; +use crate::serialize::pytket::error::BarrierPayloadError; use crate::serialize::pytket::extension::RegisterCount; use crate::serialize::pytket::opaque::{ EncodedEdgeID, OpaqueSubgraph, OpaqueSubgraphPayload, SubgraphId, @@ -269,7 +270,7 @@ impl<'h> PytketDecoderContext<'h> { params: &[LoadedParameter], ) -> Result { let to_insert_hugr = Hugr::load_str(hugr_envelope, Some(self.extension_registry())) - .map_err(|e| PytketDecodeErrorInner::UnsupportedSubgraphInlinePayload { source: e })?; + .map_err(|e| BarrierPayloadError::HugrRead(e).wrap())?; let to_insert_signature = to_insert_hugr.inner_function_type().unwrap(); let module = self.builder.hugr().module_root(); diff --git a/tket/src/serialize/pytket/error.rs b/tket/src/serialize/pytket/error.rs index 09550297a..dc9783c27 100644 --- a/tket/src/serialize/pytket/error.rs +++ b/tket/src/serialize/pytket/error.rs @@ -3,7 +3,7 @@ use derive_more::{Display, Error, From}; use hugr::Wire; use hugr::core::HugrNode; -use hugr::envelope::EnvelopeError; +use hugr::extension::resolution::ExtensionResolutionError; use hugr::ops::OpType; use itertools::Itertools; use tket_json_rs::register::ElementId; @@ -450,13 +450,8 @@ pub enum PytketDecodeErrorInner { id: SubgraphId, }, /// Cannot decode Hugr from an unsupported subgraph payload in a pytket barrier operation. - #[display( - "Cannot decode Hugr from an inline subgraph payload in a pytket barrier operation. {source}" - )] - UnsupportedSubgraphInlinePayload { - /// The envelope decoding error. - source: EnvelopeError, - }, + #[display("{_0}")] + UnsupportedBarrierPayload(BarrierPayloadError), /// Cannot translate a wire from one type to another. #[display("Cannot translate {wire} from type {initial_type} to type {target_type}{}", context.as_ref().map(|s| format!(". {s}")).unwrap_or_default() @@ -479,3 +474,27 @@ impl PytketDecodeErrorInner { PytketDecodeError::from(self) } } + +/// Sub-errors for [PytketDecodeError] raised when the payload of an opaque +/// pytket barrier fails to be decoded as a +/// [OpaqueSubgraphPayload][super::opaque::OpaqueSubgraphPayload]. +#[derive(derive_more::Debug, Display, Error)] +#[non_exhaustive] +pub enum BarrierPayloadError { + /// Cannot decode the payload as a JSON string. + #[display("Cannot decode the opaque subgraph payload from a JSON string. {_0}")] + SerdeDecoding(serde_json::Error), + /// Cannot decode the Hugr encoded in an opaque subgraph payload. + #[display("Cannot decode the Hugr encoded in an opaque subgraph payload. {_0}")] + HugrRead(hugr::envelope::ReadError), + /// Cannot resolve the extension references in the opaque subgraph payload. + #[display("Cannot resolve the extension references in the opaque subgraph payload. {_0}")] + ExtensionResolution(ExtensionResolutionError), +} + +impl BarrierPayloadError { + /// Wrap the error in a [PytketDecodeError]. + pub fn wrap(self) -> PytketDecodeError { + PytketDecodeErrorInner::UnsupportedBarrierPayload(self).wrap() + } +} diff --git a/tket/src/serialize/pytket/opaque/payload.rs b/tket/src/serialize/pytket/opaque/payload.rs index b7827993d..c9a484bca 100644 --- a/tket/src/serialize/pytket/opaque/payload.rs +++ b/tket/src/serialize/pytket/opaque/payload.rs @@ -1,7 +1,7 @@ //! Definitions of the payloads for opaque barrier metadata in pytket circuits. use hugr::core::HugrNode; -use hugr::envelope::{EnvelopeConfig, EnvelopeError}; +use hugr::envelope::EnvelopeConfig; use hugr::extension::resolution::{WeakExtensionRegistry, resolve_type_extensions}; use hugr::extension::{ExtensionRegistry, ExtensionRegistryLoadError}; use hugr::package::Package; @@ -9,6 +9,7 @@ use hugr::types::Type; use hugr::{HugrView, Wire}; use itertools::Itertools; +use crate::serialize::pytket::error::BarrierPayloadError; use crate::serialize::pytket::opaque::OpaqueSubgraph; use crate::serialize::pytket::{ PytketDecodeError, PytketDecodeErrorInner, PytketEncodeError, PytketEncodeOpError, @@ -192,12 +193,8 @@ impl OpaqueSubgraphPayload { /// /// Updates weak extension references inside the definition after loading. pub fn load_str(json: &str, extensions: &ExtensionRegistry) -> Result { - let mut payload: Self = serde_json::from_str(json).map_err(|e| { - PytketDecodeErrorInner::UnsupportedSubgraphInlinePayload { - source: EnvelopeError::SerdeError { source: e }, - } - .wrap() - })?; + let mut payload: Self = + serde_json::from_str(json).map_err(|e| BarrierPayloadError::SerdeDecoding(e).wrap())?; // Resolve the extension ops and types in the inline payload. if let Self::Inline { @@ -208,15 +205,8 @@ impl OpaqueSubgraphPayload { // Resolve the cached input/output types. for (ty, _) in inputs.iter_mut().chain(outputs.iter_mut()) { - resolve_type_extensions(ty, &extensions).map_err(|e| { - let registry_load_e = - ExtensionRegistryLoadError::ExtensionResolutionError(Box::new(e)); - let envelope_e = EnvelopeError::ExtensionLoad { - source: registry_load_e, - }; - PytketDecodeErrorInner::UnsupportedSubgraphInlinePayload { source: envelope_e } - .wrap() - })?; + resolve_type_extensions(ty, &extensions) + .map_err(|e| BarrierPayloadError::ExtensionResolution(e).wrap())?; } } From ee01fea4f82ee2ae6f2361ac9a4ff9d2e5188945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 10:39:33 +0000 Subject: [PATCH 21/48] Update metadata method calls --- tket/src/circuit/command.rs | 6 +++--- tket/src/modifier.rs | 4 ++-- tket/src/modifier/modifier_resolver.rs | 4 +++- tket/src/rewrite/trace.rs | 16 ++++++++++------ tket/src/serialize/pytket/decoder.rs | 19 +++++++++++++++---- tket/src/serialize/pytket/encoder.rs | 4 ++-- .../serialize/pytket/encoder/value_tracker.rs | 2 +- tket/src/serialize/pytket/tests.rs | 4 ++-- 8 files changed, 38 insertions(+), 21 deletions(-) diff --git a/tket/src/circuit/command.rs b/tket/src/circuit/command.rs index 309030546..592ba5cc1 100644 --- a/tket/src/circuit/command.rs +++ b/tket/src/circuit/command.rs @@ -6,7 +6,7 @@ use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::iter::FusedIterator; -use hugr::hugr::NodeMetadata; +use hugr::metadata::{Metadata, RawMetadataValue}; use hugr::ops::{OpTag, OpTrait}; use hugr::{HugrView, IncomingPort, OutgoingPort}; use hugr_core::hugr::internal::{HugrInternals, PortgraphNodeMap}; @@ -159,8 +159,8 @@ impl<'circ, T: HugrView> Command<'circ, T> { /// Returns a metadata value associated with the command's node. #[inline] - pub fn metadata(&self, key: impl AsRef) -> Option<&NodeMetadata> { - self.circ.hugr().get_metadata(self.node, key) + pub fn metadata(&self) -> Option> { + self.circ.hugr().get_metadata::(self.node) } } diff --git a/tket/src/modifier.rs b/tket/src/modifier.rs index ad52c77b6..a5afb06bf 100644 --- a/tket/src/modifier.rs +++ b/tket/src/modifier.rs @@ -63,7 +63,7 @@ struct ModifierFlags { impl ModifierFlags { fn from_metadata(h: &impl HugrView, n: N) -> Option { - h.get_metadata(n, "unitary") + h.get_metadata_any(n, "unitary") .and_then(serde_json::Value::as_u64) .map(|num| ModifierFlags { dagger: (num & 1) != 0, @@ -83,7 +83,7 @@ impl ModifierFlags { if self.power { num |= 4; } - *h.get_metadata_mut(n, "unitary") = serde_json::Value::from(num); + h.set_metadata_any(n, "unitary", serde_json::Value::from(num)); } fn satisfies(&self, combined: &CombinedModifier) -> bool { diff --git a/tket/src/modifier/modifier_resolver.rs b/tket/src/modifier/modifier_resolver.rs index e4f3efe9c..d4f614dfd 100644 --- a/tket/src/modifier/modifier_resolver.rs +++ b/tket/src/modifier/modifier_resolver.rs @@ -1164,7 +1164,9 @@ mod tests { } impl SetUnitary for T { fn set_unitary(&mut self) { - self.set_metadata("unitary", 7); + // TODO: Use `self.set_metadata::<...>(7)` once we implement metadata keys in tket. + let node = self.container_node(); + self.hugr_mut().set_metadata_any(node, "unitary", 7); } } diff --git a/tket/src/rewrite/trace.rs b/tket/src/rewrite/trace.rs index 0306260a0..9706ce580 100644 --- a/tket/src/rewrite/trace.rs +++ b/tket/src/rewrite/trace.rs @@ -2,8 +2,8 @@ //! //! This is only tracked if the `rewrite-tracing` feature is enabled. -use hugr::hugr::NodeMetadata; use hugr::hugr::hugrmut::HugrMut; +use hugr::metadata::RawMetadataValue; use itertools::Itertools; use crate::Circuit; @@ -79,9 +79,11 @@ impl Circuit { return; } let root = self.parent(); - let meta = self.hugr_mut().get_metadata_mut(root, METADATA_REWRITES); - if *meta == NodeMetadata::Null { - *meta = NodeMetadata::Array(vec![]); + let meta = self + .hugr_mut() + .get_metadata_any_mut(root, METADATA_REWRITES); + if *meta == RawMetadataValue::Null { + *meta = RawMetadataValue::Array(vec![]); } } @@ -96,7 +98,7 @@ impl Circuit { let root = self.parent(); match self .hugr_mut() - .get_metadata_mut(root, METADATA_REWRITES) + .get_metadata_any_mut(root, METADATA_REWRITES) .as_array_mut() { Some(meta) => { @@ -117,7 +119,9 @@ impl Circuit { if !REWRITE_TRACING_ENABLED { return None; } - let meta = self.hugr().get_metadata(self.parent(), METADATA_REWRITES)?; + let meta = self + .hugr() + .get_metadata_any(self.parent(), METADATA_REWRITES)?; let rewrites = meta.as_array()?; Some(rewrites.iter().map_into()) } diff --git a/tket/src/serialize/pytket/decoder.rs b/tket/src/serialize/pytket/decoder.rs index 45597a688..863250cf5 100644 --- a/tket/src/serialize/pytket/decoder.rs +++ b/tket/src/serialize/pytket/decoder.rs @@ -178,9 +178,16 @@ impl<'h> PytketDecoderContext<'h> { fn init_metadata(dfg: &mut DFGBuilder<&mut Hugr>, serialcirc: &SerialCircuit) { // Metadata. The circuit requires "name", and we store other things that // should pass through the serialization roundtrip. - dfg.set_metadata(METADATA_PHASE, json!(serialcirc.phase)); - dfg.set_metadata(METADATA_Q_REGISTERS, json!(serialcirc.qubits)); - dfg.set_metadata(METADATA_B_REGISTERS, json!(serialcirc.bits)); + + // TODO: Replace these with `dfg.set_metadata::<...>(...)` once we + // implement metadata keys in tket. + let node = dfg.container_node(); + dfg.hugr_mut() + .set_metadata_any(node, METADATA_PHASE, json!(serialcirc.phase)); + dfg.hugr_mut() + .set_metadata_any(node, METADATA_Q_REGISTERS, json!(serialcirc.qubits)); + dfg.hugr_mut() + .set_metadata_any(node, METADATA_B_REGISTERS, json!(serialcirc.bits)); } /// Initialize the wire tracker with the input wires. @@ -434,7 +441,11 @@ impl<'h> PytketDecoderContext<'h> { // Store the name for the input parameter wires let input_params = self.wire_tracker.finish(); if !input_params.is_empty() { - self.builder.set_metadata( + // TODO: Replace this with `self.builder.set_metadata::<...>(...)` once we + // implement metadata keys in tket. + let node = self.builder.container_node(); + self.builder.hugr_mut().set_metadata_any( + node, METADATA_INPUT_PARAMETERS, json!(input_params.into_iter().collect_vec()), ); diff --git a/tket/src/serialize/pytket/encoder.rs b/tket/src/serialize/pytket/encoder.rs index 1dc9f1bf2..0b2cee394 100644 --- a/tket/src/serialize/pytket/encoder.rs +++ b/tket/src/serialize/pytket/encoder.rs @@ -170,7 +170,7 @@ impl PytketEncoderContext { .filter(|s| !s.is_empty()); // Recover other parameters stored in the metadata - let phase = match hugr.get_metadata(region, METADATA_PHASE) { + let phase = match hugr.get_metadata_any(region, METADATA_PHASE) { Some(p) => p.as_str().unwrap().to_string(), None => "0".to_string(), }; @@ -462,7 +462,7 @@ impl PytketEncoderContext { // Preserve the pytket opgroup, if it got stored in the metadata. let opgroup: Option = circ .hugr() - .get_metadata(node, METADATA_OPGROUP) + .get_metadata_any(node, METADATA_OPGROUP) .and_then(serde_json::Value::as_str) .map(ToString::to_string); diff --git a/tket/src/serialize/pytket/encoder/value_tracker.rs b/tket/src/serialize/pytket/encoder/value_tracker.rs index 227fd540c..f3ac2e5cd 100644 --- a/tket/src/serialize/pytket/encoder/value_tracker.rs +++ b/tket/src/serialize/pytket/encoder/value_tracker.rs @@ -580,7 +580,7 @@ fn read_metadata_json_list( region: H::Node, metadata_key: &str, ) -> Vec { - let Some(value) = circ.hugr().get_metadata(region, metadata_key) else { + let Some(value) = circ.hugr().get_metadata_any(region, metadata_key) else { return vec![]; }; diff --git a/tket/src/serialize/pytket/tests.rs b/tket/src/serialize/pytket/tests.rs index d03b3aae2..2853738cb 100644 --- a/tket/src/serialize/pytket/tests.rs +++ b/tket/src/serialize/pytket/tests.rs @@ -250,7 +250,7 @@ fn circ_preset_qubits() -> Circuit { let mut hugr = h.finish_hugr_with_outputs([qb0, qb1]).unwrap(); // A preset register for the first qubit output - hugr.set_metadata( + hugr.set_metadata_any( hugr.entrypoint(), METADATA_Q_REGISTERS, serde_json::json!([["q", [2]], ["q", [10]], ["q", [8]]]), @@ -284,7 +284,7 @@ fn circ_parameterized() -> Circuit { let mut hugr = h.finish_hugr_with_outputs([q]).unwrap(); // Preset names for some of the inputs - hugr.set_metadata( + hugr.set_metadata_any( hugr.entrypoint(), METADATA_INPUT_PARAMETERS, serde_json::json!(["alpha", "beta"]), From 350057b92acd447eb2e113b22bcb29a4d5fc442c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 10:45:01 +0000 Subject: [PATCH 22/48] SiblingSubgraph requires RootChecked --- tket/src/circuit.rs | 7 +++++-- tket/src/ops.rs | 4 ++-- tket/src/passes/chunks.rs | 7 +++++-- tket/src/resource.rs | 8 ++++++-- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/tket/src/circuit.rs b/tket/src/circuit.rs index 805f85ccc..0075179b1 100644 --- a/tket/src/circuit.rs +++ b/tket/src/circuit.rs @@ -15,7 +15,7 @@ pub use hash::CircuitHash; use hugr::extension::prelude::{NoopDef, TupleOpDef}; use hugr::extension::simple_op::MakeOpDef; use hugr::hugr::views::sibling_subgraph::InvalidSubgraph; -use hugr::hugr::views::{ExtractionResult, SiblingSubgraph}; +use hugr::hugr::views::{ExtractionResult, RootChecked, SiblingSubgraph}; use hugr::ops::handle::DataflowParentID; use itertools::Either::{Left, Right}; @@ -351,7 +351,10 @@ impl> Circuit { where T: Clone, { - SiblingSubgraph::try_new_dataflow_subgraph::<_, DataflowParentID>(self.hugr()) + let Ok(checked) = RootChecked::try_new(self.hugr()) else { + return Err(InvalidSubgraph::NonDataflowRegion); + }; + SiblingSubgraph::try_new_dataflow_subgraph::<_, DataflowParentID>(checked) } /// Compute the cost of the circuit based on a per-operation cost function. diff --git a/tket/src/ops.rs b/tket/src/ops.rs index d691474fc..a9b5c88f9 100644 --- a/tket/src/ops.rs +++ b/tket/src/ops.rs @@ -312,8 +312,8 @@ impl MakeRegisteredOp for TketOp { EXTENSION_ID.to_owned() } - fn extension_ref(&self) -> Weak { - Arc::::downgrade(&TKET_EXTENSION) + fn extension_ref(&self) -> Arc { + TKET_EXTENSION.clone() } } diff --git a/tket/src/passes/chunks.rs b/tket/src/passes/chunks.rs index abdeaeae3..b61a28919 100644 --- a/tket/src/passes/chunks.rs +++ b/tket/src/passes/chunks.rs @@ -9,8 +9,8 @@ use std::ops::{Index, IndexMut}; use derive_more::From; use hugr::builder::{Container, FunctionBuilder}; use hugr::hugr::hugrmut::HugrMut; -use hugr::hugr::views::SiblingSubgraph; use hugr::hugr::views::sibling_subgraph::TopoConvexChecker; +use hugr::hugr::views::{RootChecked, SiblingSubgraph}; use hugr::hugr::{HugrError, NodeMetadataMap}; use hugr::ops::OpType; use hugr::ops::handle::DataflowParentID; @@ -107,8 +107,11 @@ impl Chunk { let [chunk_inp, chunk_out] = chunk.get_io(chunk_root).unwrap(); // Insert the chunk circuit into the original circuit. + let Ok(checked) = RootChecked::try_new(&chunk) else { + panic!("The chunk circuit is no longer a dataflow graph"); + }; let subgraph = - SiblingSubgraph::::try_new_dataflow_subgraph::<_, DataflowParentID>(&chunk) + SiblingSubgraph::::try_new_dataflow_subgraph::<_, DataflowParentID>(checked) .unwrap_or_else(|e| panic!("The chunk circuit is no longer a dataflow graph: {e}")); let node_map = circ.insert_subgraph(root, &chunk, &subgraph); diff --git a/tket/src/resource.rs b/tket/src/resource.rs index 3a1e3ce98..339e83e27 100644 --- a/tket/src/resource.rs +++ b/tket/src/resource.rs @@ -154,9 +154,13 @@ pub(crate) mod tests { #[case] add_rz: bool, #[case] add_const_rz: bool, ) { + use hugr::hugr::views::RootChecked; + let circ = circ(n_qubits, add_rz, add_const_rz); - let subgraph = - SiblingSubgraph::try_new_dataflow_subgraph::<_, DataflowParentID>(&circ).unwrap(); + let subgraph = SiblingSubgraph::try_new_dataflow_subgraph::<_, DataflowParentID>( + RootChecked::try_new(&circ).expect("Entrypoint should be a dataflow parent."), + ) + .unwrap(); let scope = ResourceScope::new(&circ, subgraph); let info = ResourceScopeReport::from(&scope); From d572aa4458b2b08622739f7f7d108957ee1efa26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 10:46:05 +0000 Subject: [PATCH 23/48] Extension definitions return an Arc rather than Weak --- tket-qsystem/src/extension/classical_compute/gpu.rs | 4 ++-- tket-qsystem/src/extension/classical_compute/wasm.rs | 4 ++-- tket-qsystem/src/extension/futures.rs | 4 ++-- tket-qsystem/src/extension/qsystem.rs | 4 ++-- tket-qsystem/src/extension/qsystem/lower.rs | 4 ++-- tket-qsystem/src/extension/random.rs | 4 ++-- tket-qsystem/src/extension/utils.rs | 4 ++-- tket/src/circuit/command.rs | 2 +- tket/src/extension/bool.rs | 4 ++-- tket/src/extension/debug.rs | 4 ++-- tket/src/extension/global_phase.rs | 4 ++-- tket/src/extension/rotation.rs | 4 ++-- tket/src/extension/sympy.rs | 4 ++-- tket/src/passes/unpack_container/op_function_map.rs | 2 +- tket/src/serialize/pytket/opaque/payload.rs | 6 ++---- 15 files changed, 28 insertions(+), 30 deletions(-) diff --git a/tket-qsystem/src/extension/classical_compute/gpu.rs b/tket-qsystem/src/extension/classical_compute/gpu.rs index f2eb103c7..56818ba2d 100644 --- a/tket-qsystem/src/extension/classical_compute/gpu.rs +++ b/tket-qsystem/src/extension/classical_compute/gpu.rs @@ -165,8 +165,8 @@ impl MakeRegisteredOp for GpuOp { EXTENSION_ID } - fn extension_ref(&self) -> Weak { - Arc::downgrade(&EXTENSION) + fn extension_ref(&self) -> Arc { + EXTENSION.clone() } } diff --git a/tket-qsystem/src/extension/classical_compute/wasm.rs b/tket-qsystem/src/extension/classical_compute/wasm.rs index c871e672d..cb48c8b1f 100644 --- a/tket-qsystem/src/extension/classical_compute/wasm.rs +++ b/tket-qsystem/src/extension/classical_compute/wasm.rs @@ -165,8 +165,8 @@ impl MakeRegisteredOp for WasmOp { EXTENSION_ID } - fn extension_ref(&self) -> Weak { - Arc::downgrade(&EXTENSION) + fn extension_ref(&self) -> Arc { + EXTENSION.clone() } } diff --git a/tket-qsystem/src/extension/futures.rs b/tket-qsystem/src/extension/futures.rs index 0d3a5b4e6..67e386e8c 100644 --- a/tket-qsystem/src/extension/futures.rs +++ b/tket-qsystem/src/extension/futures.rs @@ -196,8 +196,8 @@ impl MakeRegisteredOp for FutureOp { EXTENSION_ID } - fn extension_ref(&self) -> Weak { - Arc::downgrade(&EXTENSION) + fn extension_ref(&self) -> Arc { + EXTENSION.clone() } } diff --git a/tket-qsystem/src/extension/qsystem.rs b/tket-qsystem/src/extension/qsystem.rs index c377f3e92..40d29719a 100644 --- a/tket-qsystem/src/extension/qsystem.rs +++ b/tket-qsystem/src/extension/qsystem.rs @@ -174,8 +174,8 @@ impl MakeRegisteredOp for QSystemOp { EXTENSION_ID } - fn extension_ref(&self) -> Weak { - Arc::downgrade(&EXTENSION) + fn extension_ref(&self) -> Arc { + EXTENSION.clone() } } diff --git a/tket-qsystem/src/extension/qsystem/lower.rs b/tket-qsystem/src/extension/qsystem/lower.rs index 383d6baf6..38a0998b2 100644 --- a/tket-qsystem/src/extension/qsystem/lower.rs +++ b/tket-qsystem/src/extension/qsystem/lower.rs @@ -114,7 +114,7 @@ pub fn lower_tk2_op(hugr: &mut impl HugrMut) -> Result, L ReplaceOps::Tk2(tket_op) => { // Handle TketOp replacements if let Some(direct) = direct_map(tket_op) { - lowerer.replace_op( + lowerer.set_replace_op( &tket_op.into_extension_op(), NodeTemplate::SingleOp(direct.into()), ); @@ -130,7 +130,7 @@ pub fn lower_tk2_op(hugr: &mut impl HugrMut) -> Result, L *e.insert(inserted) } }; - lowerer.replace_op( + lowerer.set_replace_op( &tket_op.into_extension_op(), NodeTemplate::Call(func_node, vec![]), ); diff --git a/tket-qsystem/src/extension/random.rs b/tket-qsystem/src/extension/random.rs index 368fee24b..a2c251c89 100644 --- a/tket-qsystem/src/extension/random.rs +++ b/tket-qsystem/src/extension/random.rs @@ -182,8 +182,8 @@ impl MakeRegisteredOp for RandomOp { EXTENSION_ID } - fn extension_ref(&self) -> Weak { - Arc::downgrade(&EXTENSION) + fn extension_ref(&self) -> Arc { + EXTENSION.clone() } } diff --git a/tket-qsystem/src/extension/utils.rs b/tket-qsystem/src/extension/utils.rs index ef3299dfe..4fd4450a3 100644 --- a/tket-qsystem/src/extension/utils.rs +++ b/tket-qsystem/src/extension/utils.rs @@ -101,8 +101,8 @@ impl MakeRegisteredOp for UtilsOp { EXTENSION_ID } - fn extension_ref(&self) -> Weak { - Arc::downgrade(&EXTENSION) + fn extension_ref(&self) -> Arc { + EXTENSION.clone() } } diff --git a/tket/src/circuit/command.rs b/tket/src/circuit/command.rs index 592ba5cc1..960615363 100644 --- a/tket/src/circuit/command.rs +++ b/tket/src/circuit/command.rs @@ -6,7 +6,7 @@ use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::iter::FusedIterator; -use hugr::metadata::{Metadata, RawMetadataValue}; +use hugr::metadata::Metadata; use hugr::ops::{OpTag, OpTrait}; use hugr::{HugrView, IncomingPort, OutgoingPort}; use hugr_core::hugr::internal::{HugrInternals, PortgraphNodeMap}; diff --git a/tket/src/extension/bool.rs b/tket/src/extension/bool.rs index 6ef82234f..4a7d42ca2 100644 --- a/tket/src/extension/bool.rs +++ b/tket/src/extension/bool.rs @@ -184,8 +184,8 @@ impl MakeRegisteredOp for BoolOp { BOOL_EXTENSION_ID } - fn extension_ref(&self) -> Weak { - Arc::downgrade(&BOOL_EXTENSION) + fn extension_ref(&self) -> Arc { + BOOL_EXTENSION.clone() } } /// An extension trait for [Dataflow] providing methods to add "tket.bool" diff --git a/tket/src/extension/debug.rs b/tket/src/extension/debug.rs index 1a606e45b..ea089cc5c 100644 --- a/tket/src/extension/debug.rs +++ b/tket/src/extension/debug.rs @@ -141,8 +141,8 @@ impl MakeRegisteredOp for StateResult { DEBUG_EXTENSION_ID } - fn extension_ref(&self) -> Weak { - Arc::downgrade(&DEBUG_EXTENSION) + fn extension_ref(&self) -> Arc { + DEBUG_EXTENSION.clone() } } diff --git a/tket/src/extension/global_phase.rs b/tket/src/extension/global_phase.rs index 441ff99fa..a687c69e3 100644 --- a/tket/src/extension/global_phase.rs +++ b/tket/src/extension/global_phase.rs @@ -107,8 +107,8 @@ impl MakeRegisteredOp for GlobalPhase { GLOBAL_PHASE_EXTENSION_ID.to_owned() } - fn extension_ref(&self) -> Weak { - Arc::::downgrade(&GLOBAL_PHASE_EXTENSION) + fn extension_ref(&self) -> Arc { + GLOBAL_PHASE_EXTENSION.clone() } } diff --git a/tket/src/extension/rotation.rs b/tket/src/extension/rotation.rs index ceca61f87..0d4d71eac 100644 --- a/tket/src/extension/rotation.rs +++ b/tket/src/extension/rotation.rs @@ -196,8 +196,8 @@ impl MakeRegisteredOp for RotationOp { ROTATION_EXTENSION_ID } - fn extension_ref(&self) -> Weak { - Arc::downgrade(&ROTATION_EXTENSION) + fn extension_ref(&self) -> Arc { + ROTATION_EXTENSION.clone() } } diff --git a/tket/src/extension/sympy.rs b/tket/src/extension/sympy.rs index 28c8ccb0a..62bde774a 100644 --- a/tket/src/extension/sympy.rs +++ b/tket/src/extension/sympy.rs @@ -112,8 +112,8 @@ impl MakeRegisteredOp for SympyOp { TKET_EXTENSION_ID.to_owned() } - fn extension_ref(&self) -> Weak { - Arc::downgrade(&TKET_EXTENSION) + fn extension_ref(&self) -> Arc { + TKET_EXTENSION.clone() } } diff --git a/tket/src/passes/unpack_container/op_function_map.rs b/tket/src/passes/unpack_container/op_function_map.rs index 24f9c5431..dd2eeb871 100644 --- a/tket/src/passes/unpack_container/op_function_map.rs +++ b/tket/src/passes/unpack_container/op_function_map.rs @@ -120,7 +120,7 @@ impl OpFunctionMap { let func_node = hugr .insert_hugr(hugr.module_root(), func_def) .inserted_entrypoint; - lowerer.replace_op(&op, NodeTemplate::Call(func_node, vec![])); + lowerer.set_replace_op(&op, NodeTemplate::Call(func_node, vec![])); } } } diff --git a/tket/src/serialize/pytket/opaque/payload.rs b/tket/src/serialize/pytket/opaque/payload.rs index c9a484bca..dde10ec44 100644 --- a/tket/src/serialize/pytket/opaque/payload.rs +++ b/tket/src/serialize/pytket/opaque/payload.rs @@ -2,8 +2,8 @@ use hugr::core::HugrNode; use hugr::envelope::EnvelopeConfig; +use hugr::extension::ExtensionRegistry; use hugr::extension::resolution::{WeakExtensionRegistry, resolve_type_extensions}; -use hugr::extension::{ExtensionRegistry, ExtensionRegistryLoadError}; use hugr::package::Package; use hugr::types::Type; use hugr::{HugrView, Wire}; @@ -11,9 +11,7 @@ use itertools::Itertools; use crate::serialize::pytket::error::BarrierPayloadError; use crate::serialize::pytket::opaque::OpaqueSubgraph; -use crate::serialize::pytket::{ - PytketDecodeError, PytketDecodeErrorInner, PytketEncodeError, PytketEncodeOpError, -}; +use crate::serialize::pytket::{PytketDecodeError, PytketEncodeError, PytketEncodeOpError}; use super::SubgraphId; From ba45b1962abdbeaada61e12e0d97ee952925e072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 11:06:53 +0000 Subject: [PATCH 24/48] Replace deprecated ReplaceTypes::replace_op --- tket-qsystem/src/extension/result.rs | 4 ++-- tket-qsystem/src/extension/utils.rs | 2 +- tket-qsystem/src/lower_drops.rs | 11 +++++------ tket-qsystem/src/replace_bools.rs | 14 +++++++------- tket-qsystem/src/replace_bools/static_array.rs | 16 ++++++++-------- 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/tket-qsystem/src/extension/result.rs b/tket-qsystem/src/extension/result.rs index 67dd7f98f..b026cb117 100644 --- a/tket-qsystem/src/extension/result.rs +++ b/tket-qsystem/src/extension/result.rs @@ -376,8 +376,8 @@ impl MakeRegisteredOp for ResultOp { EXTENSION_ID } - fn extension_ref(&self) -> Weak { - Arc::downgrade(&EXTENSION) + fn extension_ref(&self) -> Arc { + EXTENSION.clone() } } diff --git a/tket-qsystem/src/extension/utils.rs b/tket-qsystem/src/extension/utils.rs index 4fd4450a3..41ae1cfb9 100644 --- a/tket-qsystem/src/extension/utils.rs +++ b/tket-qsystem/src/extension/utils.rs @@ -1,7 +1,7 @@ //! This module defines the "tket.qsystem.utils" extension, which includes the //! utility functions available for Quantinuum systems. -use std::sync::{Arc, Weak}; +use std::sync::Arc; use derive_more::derive::Display; use hugr::{ diff --git a/tket-qsystem/src/lower_drops.rs b/tket-qsystem/src/lower_drops.rs index 4f5c91c61..c257e3ae8 100644 --- a/tket-qsystem/src/lower_drops.rs +++ b/tket-qsystem/src/lower_drops.rs @@ -1,5 +1,5 @@ /// Contains a pass to lower "drop" ops from the Guppy extension -use hugr::algorithms::replace_types::{NodeTemplate, ReplaceTypesError, ReplacementOptions}; +use hugr::algorithms::replace_types::{NodeTemplate, ReplaceTypesError}; use hugr::algorithms::{ComposablePass, ReplaceTypes}; use hugr::builder::{Container, DFGBuilder}; use hugr::extension::prelude::bool_t; @@ -38,7 +38,7 @@ impl> ComposablePass for LowerDropsPass { } .to_extension_op() .unwrap(); - rt.linearizer() + rt.linearizer_mut() .register_simple( future_type(bool_t()).as_extension().unwrap().clone(), NodeTemplate::SingleOp(dup_op.into()), @@ -46,18 +46,17 @@ impl> ComposablePass for LowerDropsPass { ) .unwrap(); - rt.replace_parametrized_op_with( + rt.set_replace_parametrized_op( GUPPY_EXTENSION.get_op(DROP_OP_NAME.as_str()).unwrap(), - |targs| { + |targs, _| { let [Term::Runtime(ty)] = targs else { panic!("Expected just one type") }; // The Hugr here is invalid, so we have to pull it out manually let mut dfb = DFGBuilder::new(Signature::new(ty.clone(), vec![])).unwrap(); let h = std::mem::take(dfb.hugr_mut()); - Some(NodeTemplate::CompoundOp(Box::new(h))) + Ok(Some(NodeTemplate::CompoundOp(Box::new(h)))) }, - ReplacementOptions::default().with_linearization(true), ); rt.run(hugr) } diff --git a/tket-qsystem/src/replace_bools.rs b/tket-qsystem/src/replace_bools.rs index f5056a8a2..1db0a869b 100644 --- a/tket-qsystem/src/replace_bools.rs +++ b/tket-qsystem/src/replace_bools.rs @@ -337,22 +337,22 @@ fn lowerer() -> ReplaceTypes { // Replace all tket.bool ops. let read_op = BoolOp::read.to_extension_op().unwrap(); - lw.replace_op(&read_op, read_op_dest()); + lw.set_replace_op(&read_op, read_op_dest()); let make_opaque_op = BoolOp::make_opaque.to_extension_op().unwrap(); - lw.replace_op(&make_opaque_op, make_opaque_op_dest()); + lw.set_replace_op(&make_opaque_op, make_opaque_op_dest()); for op in [BoolOp::eq, BoolOp::and, BoolOp::or, BoolOp::xor] { - lw.replace_op(&op.to_extension_op().unwrap(), binary_logic_op_dest(&op)); + lw.set_replace_op(&op.to_extension_op().unwrap(), binary_logic_op_dest(&op)); } let not_op = BoolOp::not.to_extension_op().unwrap(); - lw.replace_op(¬_op, not_op_dest()); + lw.set_replace_op(¬_op, not_op_dest()); // Replace measure ops with lazy versions. let tket_measure_free = TketOp::MeasureFree.to_extension_op().unwrap(); let qsystem_measure = QSystemOp::Measure.to_extension_op().unwrap(); let qsystem_measure_reset = QSystemOp::MeasureReset.to_extension_op().unwrap(); - lw.replace_op(&tket_measure_free, measure_dest()); - lw.replace_op(&qsystem_measure, measure_dest()); - lw.replace_op(&qsystem_measure_reset, measure_reset_dest()); + lw.set_replace_op(&tket_measure_free, measure_dest()); + lw.set_replace_op(&qsystem_measure, measure_dest()); + lw.set_replace_op(&qsystem_measure_reset, measure_reset_dest()); // Replace (borrow/)array ops that used to have with copyable bounds with DFGs that // the linearizer can act on now that the elements are no longer copyable. diff --git a/tket-qsystem/src/replace_bools/static_array.rs b/tket-qsystem/src/replace_bools/static_array.rs index 84e54cbfb..6cee3e3fe 100644 --- a/tket-qsystem/src/replace_bools/static_array.rs +++ b/tket-qsystem/src/replace_bools/static_array.rs @@ -72,7 +72,7 @@ fn inner_replace_types() -> ReplaceTypes { }; replace_const_static_array(sav, rt) }); - inner.replace_type(bool_type().as_extension().unwrap().clone(), bool_t()); + inner.set_replace_type(bool_type().as_extension().unwrap().clone(), bool_t()); inner.replace_consts( bool_type().as_extension().unwrap().clone(), |const_bool, _| { @@ -120,7 +120,7 @@ fn outer_replace_types() -> ReplaceTypes { replace_const_static_array(sav, &inner) } }); - outer.replace_parametrized_type(static_array_typedef, { + outer.set_replace_parametrized_type(static_array_typedef, { let inner = inner.clone(); move |args| { let mut element_ty = { @@ -133,25 +133,25 @@ fn outer_replace_types() -> ReplaceTypes { changed.then_some(static_array_type(element_ty)) } }); - outer.replace_parametrized_op( + outer.set_replace_parametrized_op( static_array::EXTENSION .get_op(&StaticArrayOpDef::get.opdef_id()) .unwrap(), { let inner = inner.clone(); - move |args| { + move |args, _| { let [element_ty] = args else { unreachable!() }; - get_op_dest(&inner, element_ty.as_runtime().unwrap()) + Ok(get_op_dest(&inner, element_ty.as_runtime().unwrap())) } }, ); - outer.replace_parametrized_op( + outer.set_replace_parametrized_op( static_array::EXTENSION .get_op(&StaticArrayOpDef::len.opdef_id()) .unwrap(), - move |args| { + move |args, _| { let [element_ty] = args else { unreachable!() }; - len_op_dest(&inner, element_ty.as_runtime().unwrap()) + Ok(len_op_dest(&inner, element_ty.as_runtime().unwrap())) }, ); outer From 7944c50adb379dfc9bc11f0690d88743fc043a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 12:07:44 +0000 Subject: [PATCH 25/48] inkwell breaking changes --- tket-qsystem/src/llvm/futures.rs | 4 ++-- tket-qsystem/src/llvm/qsystem.rs | 10 +++++----- tket-qsystem/src/llvm/random.rs | 2 +- tket-qsystem/src/llvm/utils.rs | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tket-qsystem/src/llvm/futures.rs b/tket-qsystem/src/llvm/futures.rs index 73fd64d05..993f744b9 100644 --- a/tket-qsystem/src/llvm/futures.rs +++ b/tket-qsystem/src/llvm/futures.rs @@ -150,7 +150,7 @@ impl<'c, H: HugrView> FuturesEmitter<'c, '_, '_, H> { .builder() .build_call(read_func, &[arg.into()], "read_bool")? .try_as_basic_value() - .unwrap_left() + .unwrap_basic() .into_int_value(); let dec_refcount_func = self.get_func_dec_refcount()?; self.builder() @@ -172,7 +172,7 @@ impl<'c, H: HugrView> FuturesEmitter<'c, '_, '_, H> { .builder() .build_call(read_func, &[arg.into()], "read_uint")? .try_as_basic_value() - .unwrap_left(); + .unwrap_basic(); let dec_refcount_func = self.get_func_dec_refcount()?; self.builder() .build_call(dec_refcount_func, &[arg.into()], "dec_refcount")?; diff --git a/tket-qsystem/src/llvm/qsystem.rs b/tket-qsystem/src/llvm/qsystem.rs index 7f89986c3..8dc4e83f5 100644 --- a/tket-qsystem/src/llvm/qsystem.rs +++ b/tket-qsystem/src/llvm/qsystem.rs @@ -181,7 +181,7 @@ impl QSystemCodegenExtension { "measure_i1", )? .try_as_basic_value() - .unwrap_left() + .unwrap_basic() .into_int_value(); let result = builder.build_select(result_i1, true_val, false_val, "measure")?; if op == QSystemOp::Measure { @@ -217,7 +217,7 @@ impl QSystemCodegenExtension { "lazy_measure", )? .try_as_basic_value() - .unwrap_left(); + .unwrap_basic(); builder.build_call( self.runtime_func(context, RuntimeFunction::QFree)?, &[qb.into()], @@ -239,7 +239,7 @@ impl QSystemCodegenExtension { "lazy_measure_leaked", )? .try_as_basic_value() - .unwrap_left(); + .unwrap_basic(); builder.build_call( self.runtime_func(context, RuntimeFunction::QFree)?, &[qb.into()], @@ -260,7 +260,7 @@ impl QSystemCodegenExtension { "lazy_measure", )? .try_as_basic_value() - .unwrap_left(); + .unwrap_basic(); builder.build_call( self.runtime_func(context, RuntimeFunction::Reset)?, &[qb.into()], @@ -283,7 +283,7 @@ impl QSystemCodegenExtension { "qalloc", )? .try_as_basic_value() - .unwrap_left(); + .unwrap_basic(); let max_qb = self .0 diff --git a/tket-qsystem/src/llvm/random.rs b/tket-qsystem/src/llvm/random.rs index 1cab4c1cb..133c09d35 100644 --- a/tket-qsystem/src/llvm/random.rs +++ b/tket-qsystem/src/llvm/random.rs @@ -87,7 +87,7 @@ impl<'c, H: HugrView> RandomEmitter<'c, '_, '_, H> { name, )? .try_as_basic_value() - .unwrap_left(); + .unwrap_basic(); args.outputs .finish(self.builder(), [result, self.rng_context()]) } diff --git a/tket-qsystem/src/llvm/utils.rs b/tket-qsystem/src/llvm/utils.rs index 75079cec2..b91a6aaab 100644 --- a/tket-qsystem/src/llvm/utils.rs +++ b/tket-qsystem/src/llvm/utils.rs @@ -44,7 +44,7 @@ fn emit_utils_op>( .builder() .build_call(fn_get_cur_shot, &[], "shot")? .try_as_basic_value() - .unwrap_left(); + .unwrap_basic(); args.outputs.finish(ctx.builder(), [result]) } } From 91ead38a7291c59b6edc1d5bd8b9c46f0dd663f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 12:10:58 +0000 Subject: [PATCH 26/48] downgrade non-weak extensions --- tket-qsystem/src/extension/classical_compute/gpu.rs | 5 +++-- tket-qsystem/src/extension/classical_compute/wasm.rs | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tket-qsystem/src/extension/classical_compute/gpu.rs b/tket-qsystem/src/extension/classical_compute/gpu.rs index 56818ba2d..7fb02e0ce 100644 --- a/tket-qsystem/src/extension/classical_compute/gpu.rs +++ b/tket-qsystem/src/extension/classical_compute/gpu.rs @@ -328,12 +328,13 @@ mod test { inputs: inputs.clone(), outputs: outputs.clone(), }; - let module_ty = GpuType::Module.get_type(op.extension_id(), &op.extension_ref()); + let extension = Arc::downgrade(&op.extension_ref()); + let module_ty = GpuType::Module.get_type(op.extension_id(), &extension); let func_ty = Type::new_extension(GpuType::func_custom_type( inputs.clone(), outputs.clone(), op.extension_id(), - &op.extension_ref(), + &extension, )); assert_eq!( op.to_extension_op().unwrap().signature(), diff --git a/tket-qsystem/src/extension/classical_compute/wasm.rs b/tket-qsystem/src/extension/classical_compute/wasm.rs index cb48c8b1f..91b5e22bf 100644 --- a/tket-qsystem/src/extension/classical_compute/wasm.rs +++ b/tket-qsystem/src/extension/classical_compute/wasm.rs @@ -309,12 +309,13 @@ mod test { inputs: inputs.clone(), outputs: outputs.clone(), }; - let module_ty = WasmType::Module.get_type(op.extension_id(), &op.extension_ref()); + let extension = Arc::downgrade(&op.extension_ref()); + let module_ty = WasmType::Module.get_type(op.extension_id(), &extension); let func_ty = Type::new_extension(WasmType::func_custom_type( inputs.clone(), outputs.clone(), op.extension_id(), - &op.extension_ref(), + &extension, )); assert_eq!( op.to_extension_op().unwrap().signature(), From a193513c6200d6d57126fa82295da117e0b0b357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 12:18:23 +0000 Subject: [PATCH 27/48] pyo3 breaking changes --- tket-py/src/circuit/convert.rs | 2 +- tket-py/src/circuit/tk2circuit.rs | 2 +- tket-py/src/optimiser.rs | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tket-py/src/circuit/convert.rs b/tket-py/src/circuit/convert.rs index 09c1fb674..3d0d0e52d 100644 --- a/tket-py/src/circuit/convert.rs +++ b/tket-py/src/circuit/convert.rs @@ -63,7 +63,7 @@ where E: ConvertPyErr, F: FnOnce(Circuit, CircuitType) -> Result, { - let (circ, typ) = match Tk2Circuit::extract_bound(circ) { + let (circ, typ) = match Tk2Circuit::extract(circ.as_borrowed()) { // tket circuit Ok(t2circ) => (t2circ.circ, CircuitType::Tket), // tket1 circuit diff --git a/tket-py/src/circuit/tk2circuit.rs b/tket-py/src/circuit/tk2circuit.rs index fa61cdc9a..036612315 100644 --- a/tket-py/src/circuit/tk2circuit.rs +++ b/tket-py/src/circuit/tk2circuit.rs @@ -327,7 +327,7 @@ impl Tk2Circuit { /// /// Returns an error if the py object is not a Tk2Circuit. pub fn try_extract(circ: &Bound) -> PyResult { - circ.extract::() + circ.extract::().map_err(|e| e.into()) } } diff --git a/tket-py/src/optimiser.rs b/tket-py/src/optimiser.rs index 47ec07967..657aab05f 100644 --- a/tket-py/src/optimiser.rs +++ b/tket-py/src/optimiser.rs @@ -47,8 +47,10 @@ impl BadgerCostFunction { } } -impl<'py> FromPyObject<'py> for BadgerCostFunction { - fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult { +impl<'py> FromPyObject<'_, 'py> for BadgerCostFunction { + type Error = PyErr; + + fn extract(ob: Borrowed<'_, 'py, PyAny>) -> Result { let str = ob.extract::<&str>()?; match str { "cx" => Ok(BadgerCostFunction::CXCount), From 45d5bc327fb2de6de6bd58dabaff5a50793761d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 12:21:36 +0000 Subject: [PATCH 28/48] More deprecated fns --- tket-qsystem/src/extension/result.rs | 2 +- tket-qsystem/src/replace_bools.rs | 31 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/tket-qsystem/src/extension/result.rs b/tket-qsystem/src/extension/result.rs index b026cb117..bd3f1378f 100644 --- a/tket-qsystem/src/extension/result.rs +++ b/tket-qsystem/src/extension/result.rs @@ -1,7 +1,7 @@ //! This module defines the Hugr extension used to represent result reporting operations, //! with static string tags. //! -use std::sync::{Arc, Weak}; +use std::sync::Arc; use hugr::std_extensions::collections; use hugr::types::Signature; diff --git a/tket-qsystem/src/replace_bools.rs b/tket-qsystem/src/replace_bools.rs index 1db0a869b..dc7cc0064 100644 --- a/tket-qsystem/src/replace_bools.rs +++ b/tket-qsystem/src/replace_bools.rs @@ -295,7 +295,7 @@ fn lowerer() -> ReplaceTypes { let mut lw = ReplaceTypes::default(); // Replace tket.bool type. - lw.replace_type(bool_type().as_extension().unwrap().clone(), bool_dest()); + lw.set_replace_type(bool_type().as_extension().unwrap().clone(), bool_dest()); let dup_op = FutureOp { op: FutureOpDef::Dup, typ: bool_t(), @@ -308,7 +308,7 @@ fn lowerer() -> ReplaceTypes { } .to_extension_op() .unwrap(); - lw.linearizer() + lw.linearizer_mut() .register_simple( future_type(bool_t()).as_extension().unwrap().clone(), NodeTemplate::SingleOp(dup_op.into()), @@ -366,57 +366,56 @@ fn lowerer() -> ReplaceTypes { borrow_array_type as fn(u64, Type) -> Type, ), ] { - lw.replace_parametrized_op_with( + lw.set_replace_parametrized_op( array_ext.get_op(ARRAY_CLONE_OP_ID.as_str()).unwrap(), - move |args| { + move |args, _| { let [size, elem_ty] = args else { unreachable!() }; let size = size.as_nat().unwrap(); let elem_ty = elem_ty.as_runtime().unwrap(); - (!elem_ty.copyable()).then(|| { + let template = (!elem_ty.copyable()).then(|| { NodeTemplate::CompoundOp(Box::new(copy_dfg(type_fn(size, elem_ty.clone())))) - }) + }); + Ok(template) }, - ReplacementOptions::default().with_linearization(true), ); let drop_op_def = GUPPY_EXTENSION.get_op(DROP_OP_NAME.as_str()).unwrap(); - lw.replace_parametrized_op( + lw.set_replace_parametrized_op( array_ext.get_op(ARRAY_DISCARD_OP_ID.as_str()).unwrap(), - move |args| { + move |args, _| { let [size, elem_ty] = args else { unreachable!() }; let size = size.as_nat().unwrap(); let elem_ty = elem_ty.as_runtime().unwrap(); if elem_ty.copyable() { - return None; + return Ok(None); } let drop_op = ExtensionOp::new( drop_op_def.clone(), vec![type_fn(size, elem_ty.clone()).into()], ) .unwrap(); - Some(NodeTemplate::SingleOp(drop_op.into())) + Ok(Some(NodeTemplate::SingleOp(drop_op.into()))) }, ); } - lw.replace_parametrized_op_with( + lw.set_replace_parametrized_op( borrow_array::EXTENSION .get_op(GenericArrayOpDef::::get.opdef_id().as_str()) .unwrap(), - |args| { + |args, _| { let [Term::BoundedNat(size), Term::Runtime(elem_ty)] = args else { unreachable!() }; if elem_ty.copyable() { - return None; + return Ok(None); } - Some(barray_get_dest(*size, elem_ty.clone())) + Ok(Some(barray_get_dest(*size, elem_ty.clone()))) }, - ReplacementOptions::default().with_linearization(true), ); lw From 4844b875223cf0d99b9828b9ecf27d43814c71c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 12:28:40 +0000 Subject: [PATCH 29/48] More changes/deprecations --- qis-compiler/rust/array.rs | 4 ++-- qis-compiler/rust/gpu.rs | 34 ++++++++++++++++--------------- qis-compiler/rust/lib.rs | 10 +++++++-- qis-compiler/rust/utils.rs | 4 ++-- tket-py/src/ops.rs | 2 +- tket-qsystem/src/replace_bools.rs | 2 +- 6 files changed, 32 insertions(+), 24 deletions(-) diff --git a/qis-compiler/rust/array.rs b/qis-compiler/rust/array.rs index 64dcd1c81..ab442b1ad 100644 --- a/qis-compiler/rust/array.rs +++ b/qis-compiler/rust/array.rs @@ -32,7 +32,7 @@ impl ArrayCodegen for SeleneHeapArrayCodegen { .builder() .build_call(malloc, &[size.into()], "")? .try_as_basic_value() - .unwrap_left(); + .unwrap_basic(); Ok(res.into_pointer_value()) } @@ -77,7 +77,7 @@ impl BorrowArrayCodegen for SeleneHeapBorrowArrayCodegen>( "validate_call", )? .try_as_basic_value() - .unwrap_left() + .unwrap_basic() .into_int_value(); verify_gpu_call(ctx, success, "gpu_validate_api")?; // Mark as validated @@ -708,10 +708,11 @@ fn emit_api_validation<'c, H: HugrView>( function } }; - ctx.builder() + let _ = ctx + .builder() .build_call(func, &[], "run_gpu_validation_call")? .try_as_basic_value() - .unwrap_right(); + .unwrap_instruction(); Ok(()) } @@ -752,7 +753,7 @@ fn emit_panic_with_gpu_error<'c, H: HugrView>( .builder() .build_call(gpu_get_error, &[], "error_message")? .try_as_basic_value() - .unwrap_left() + .unwrap_basic() .into_pointer_value(); // If it's null, replace with "No error message available" @@ -771,7 +772,8 @@ fn emit_panic_with_gpu_error<'c, H: HugrView>( )?; // Call panic_str with a generic error code and the message. - ctx.builder() + let _ = ctx + .builder() .build_call( selene_specific::panic_str_fn(ctx)?, &[ @@ -781,17 +783,17 @@ fn emit_panic_with_gpu_error<'c, H: HugrView>( "panic_str_call", )? .try_as_basic_value() - .unwrap_right(); + .unwrap_instruction(); builder.build_unreachable()?; builder.position_at_end(current_block); function } Some(f) => f, }; - builder + let _ = builder .build_call(handle_error, &[], "gpu_error_handler_call")? .try_as_basic_value() - .unwrap_right(); + .unwrap_basic(); Ok(()) } @@ -841,14 +843,14 @@ fn verify_gpu_call<'c, H: HugrView>( } Some(f) => f, }; - builder + let _ = builder .build_call( handle_error, &[success_flag.into()], format!("{op_name}_handle_error").as_str(), )? .try_as_basic_value() - .unwrap_right(); + .unwrap_instruction(); Ok(()) } diff --git a/qis-compiler/rust/lib.rs b/qis-compiler/rust/lib.rs index 761f33df9..8a40bf043 100644 --- a/qis-compiler/rust/lib.rs +++ b/qis-compiler/rust/lib.rs @@ -102,6 +102,12 @@ impl From for ProcessErrs { } } +impl From for ProcessErrs { + fn from(value: inkwell::Error) -> Self { + Self(vec![value.to_string()]) + } +} + impl From for ProcessErrs { fn from(value: LLVMString) -> Self { Self(vec![value.to_string()]) @@ -270,7 +276,7 @@ fn wrap_main<'c>( let tc = builder .build_call(teardown, &[], "")? .try_as_basic_value() - .left() + .basic() .ok_or_else(|| anyhow!("get_tc has no return value"))?; // Return the initial time cursor let _ = builder.build_return(Some(&tc))?; @@ -351,7 +357,7 @@ fn compile<'c, 'hugr: 'c>( let node = ctx.metadata_node(md_vec.as_slice()); let _ = module .add_global_metadata(key, &node) - .map_err(Into::::into); + .map_err(ProcessErrs::from); } module.verify().map_err(Into::::into)?; Ok(module) diff --git a/qis-compiler/rust/utils.rs b/qis-compiler/rust/utils.rs index 652e0a4a8..ef267516c 100644 --- a/qis-compiler/rust/utils.rs +++ b/qis-compiler/rust/utils.rs @@ -1,6 +1,6 @@ use crate::REGISTRY; use anyhow::{Error, Result, anyhow}; -use tket::hugr::envelope::read_described_envelope; +use tket::hugr::envelope::read_envelope; use tket::hugr::ops::OpType; use tket::hugr::types::Term; use tket::hugr::{Hugr, HugrView}; @@ -12,7 +12,7 @@ use tket::extension::{TKET1_EXTENSION_ID, TKET1_OP_NAME}; /// Interprets the string as a hugr package and, verifies there is exactly one module in the /// package, then extracts and returns that module. pub fn read_hugr_envelope(bytes: &[u8]) -> Result { - let (desc, package) = read_described_envelope(bytes, ®ISTRY) + let (desc, package) = read_envelope(bytes, ®ISTRY) .map_err(|e| Error::new(e).context("Error loading HUGR package."))?; if package.modules.len() != 1 { diff --git a/tket-py/src/ops.rs b/tket-py/src/ops.rs index d6e23f8b5..145faf235 100644 --- a/tket-py/src/ops.rs +++ b/tket-py/src/ops.rs @@ -183,7 +183,7 @@ impl PyPauli { /// Check if two Pauli matrices are equal. pub fn __eq__(&self, other: &Bound) -> bool { - let Ok(other): Result<&Bound, _> = other.downcast() else { + let Ok(other): Result<&Bound, _> = other.cast() else { return false; }; self.p == other.borrow().p diff --git a/tket-qsystem/src/replace_bools.rs b/tket-qsystem/src/replace_bools.rs index dc7cc0064..462906e27 100644 --- a/tket-qsystem/src/replace_bools.rs +++ b/tket-qsystem/src/replace_bools.rs @@ -3,7 +3,7 @@ mod static_array; use derive_more::{Display, Error, From}; -use hugr::algorithms::replace_types::{NodeTemplate, ReplaceTypesError, ReplacementOptions}; +use hugr::algorithms::replace_types::{NodeTemplate, ReplaceTypesError}; use hugr::algorithms::{ ComposablePass, ReplaceTypes, ensure_no_nonlocal_edges, non_local::FindNonLocalEdgesError, }; From ecea580e297f6197c10d4aef9230ff68b6b59cb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 13:41:24 +0000 Subject: [PATCH 30/48] drop op in replacer --- tket-qsystem/src/lower_drops.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tket-qsystem/src/lower_drops.rs b/tket-qsystem/src/lower_drops.rs index c257e3ae8..9e1b5101a 100644 --- a/tket-qsystem/src/lower_drops.rs +++ b/tket-qsystem/src/lower_drops.rs @@ -1,10 +1,9 @@ /// Contains a pass to lower "drop" ops from the Guppy extension -use hugr::algorithms::replace_types::{NodeTemplate, ReplaceTypesError}; +use hugr::algorithms::replace_types::{Linearizer, NodeTemplate, ReplaceTypesError}; use hugr::algorithms::{ComposablePass, ReplaceTypes}; -use hugr::builder::{Container, DFGBuilder}; use hugr::extension::prelude::bool_t; use hugr::extension::simple_op::MakeRegisteredOp; -use hugr::types::{Signature, Term}; +use hugr::types::TypeArg; use hugr::{Node, hugr::hugrmut::HugrMut}; use tket::extension::guppy::{DROP_OP_NAME, GUPPY_EXTENSION}; @@ -48,14 +47,11 @@ impl> ComposablePass for LowerDropsPass { rt.set_replace_parametrized_op( GUPPY_EXTENSION.get_op(DROP_OP_NAME.as_str()).unwrap(), - |targs, _| { - let [Term::Runtime(ty)] = targs else { + |args, rt| { + let [TypeArg::Runtime(ty)] = args else { panic!("Expected just one type") }; - // The Hugr here is invalid, so we have to pull it out manually - let mut dfb = DFGBuilder::new(Signature::new(ty.clone(), vec![])).unwrap(); - let h = std::mem::take(dfb.hugr_mut()); - Ok(Some(NodeTemplate::CompoundOp(Box::new(h)))) + Ok(Some(rt.get_linearizer().copy_discard_op(ty, 0)?)) }, ); rt.run(hugr) @@ -66,7 +62,7 @@ impl> ComposablePass for LowerDropsPass { mod test { use std::sync::Arc; - use hugr::builder::{Dataflow, DataflowHugr, inout_sig}; + use hugr::builder::{DFGBuilder, Dataflow, DataflowHugr, inout_sig}; use hugr::ops::ExtensionOp; use hugr::{Hugr, HugrView}; use hugr::{extension::prelude::usize_t, std_extensions::collections::array::array_type}; From 13a21b4f397da89b32a06a6e5ecabab8bd71367e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 13:52:38 +0000 Subject: [PATCH 31/48] rollback one of the replaceTypes fixes --- tket-qsystem/src/replace_bools.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/tket-qsystem/src/replace_bools.rs b/tket-qsystem/src/replace_bools.rs index 462906e27..bc71f4015 100644 --- a/tket-qsystem/src/replace_bools.rs +++ b/tket-qsystem/src/replace_bools.rs @@ -3,7 +3,7 @@ mod static_array; use derive_more::{Display, Error, From}; -use hugr::algorithms::replace_types::{NodeTemplate, ReplaceTypesError}; +use hugr::algorithms::replace_types::{NodeTemplate, ReplaceTypesError, ReplacementOptions}; use hugr::algorithms::{ ComposablePass, ReplaceTypes, ensure_no_nonlocal_edges, non_local::FindNonLocalEdgesError, }; @@ -366,19 +366,20 @@ fn lowerer() -> ReplaceTypes { borrow_array_type as fn(u64, Type) -> Type, ), ] { - lw.set_replace_parametrized_op( + #[expect(deprecated)] // TODO: Replace with set_replace_parametrized_op + lw.replace_parametrized_op_with( array_ext.get_op(ARRAY_CLONE_OP_ID.as_str()).unwrap(), - move |args, _| { + move |args| { let [size, elem_ty] = args else { unreachable!() }; let size = size.as_nat().unwrap(); let elem_ty = elem_ty.as_runtime().unwrap(); - let template = (!elem_ty.copyable()).then(|| { + (!elem_ty.copyable()).then(|| { NodeTemplate::CompoundOp(Box::new(copy_dfg(type_fn(size, elem_ty.clone())))) - }); - Ok(template) + }) }, + ReplacementOptions::default().with_linearization(true), ); let drop_op_def = GUPPY_EXTENSION.get_op(DROP_OP_NAME.as_str()).unwrap(); @@ -403,19 +404,21 @@ fn lowerer() -> ReplaceTypes { ); } - lw.set_replace_parametrized_op( + #[expect(deprecated)] // TODO: Replace with set_replace_parametrized_op + lw.replace_parametrized_op_with( borrow_array::EXTENSION .get_op(GenericArrayOpDef::::get.opdef_id().as_str()) .unwrap(), - |args, _| { + |args| { let [Term::BoundedNat(size), Term::Runtime(elem_ty)] = args else { unreachable!() }; if elem_ty.copyable() { - return Ok(None); + return None; } - Ok(Some(barray_get_dest(*size, elem_ty.clone()))) + Some(barray_get_dest(*size, elem_ty.clone())) }, + ReplacementOptions::default().with_linearization(true), ); lw From b8210fadc55142cbd337ea0db0bb6f7369b036d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 14:19:59 +0000 Subject: [PATCH 32/48] fix unwrap --- qis-compiler/rust/gpu.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qis-compiler/rust/gpu.rs b/qis-compiler/rust/gpu.rs index f68359b3c..65eed5516 100644 --- a/qis-compiler/rust/gpu.rs +++ b/qis-compiler/rust/gpu.rs @@ -793,7 +793,7 @@ fn emit_panic_with_gpu_error<'c, H: HugrView>( let _ = builder .build_call(handle_error, &[], "gpu_error_handler_call")? .try_as_basic_value() - .unwrap_basic(); + .unwrap_instruction(); Ok(()) } From 76e005987e4de92b5466ed9958f62cfb23c6a9b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 14:35:18 +0000 Subject: [PATCH 33/48] one fewer deprecated call --- tket-qsystem/src/replace_bools.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/tket-qsystem/src/replace_bools.rs b/tket-qsystem/src/replace_bools.rs index bc71f4015..c4db2605b 100644 --- a/tket-qsystem/src/replace_bools.rs +++ b/tket-qsystem/src/replace_bools.rs @@ -3,7 +3,7 @@ mod static_array; use derive_more::{Display, Error, From}; -use hugr::algorithms::replace_types::{NodeTemplate, ReplaceTypesError, ReplacementOptions}; +use hugr::algorithms::replace_types::{Linearizer, NodeTemplate, ReplaceTypesError}; use hugr::algorithms::{ ComposablePass, ReplaceTypes, ensure_no_nonlocal_edges, non_local::FindNonLocalEdgesError, }; @@ -366,20 +366,21 @@ fn lowerer() -> ReplaceTypes { borrow_array_type as fn(u64, Type) -> Type, ), ] { - #[expect(deprecated)] // TODO: Replace with set_replace_parametrized_op - lw.replace_parametrized_op_with( + lw.set_replace_parametrized_op( array_ext.get_op(ARRAY_CLONE_OP_ID.as_str()).unwrap(), - move |args| { + move |args, rt| { let [size, elem_ty] = args else { unreachable!() }; let size = size.as_nat().unwrap(); let elem_ty = elem_ty.as_runtime().unwrap(); - (!elem_ty.copyable()).then(|| { - NodeTemplate::CompoundOp(Box::new(copy_dfg(type_fn(size, elem_ty.clone())))) - }) + if elem_ty.copyable() { + return Ok(None); + } + + let array_ty = type_fn(size, elem_ty); + Ok(Some(rt.get_linearizer().copy_discard_op(&array_ty, 2)?)) }, - ReplacementOptions::default().with_linearization(true), ); let drop_op_def = GUPPY_EXTENSION.get_op(DROP_OP_NAME.as_str()).unwrap(); @@ -418,7 +419,7 @@ fn lowerer() -> ReplaceTypes { } Some(barray_get_dest(*size, elem_ty.clone())) }, - ReplacementOptions::default().with_linearization(true), + hugr::algorithms::replace_types::ReplacementOptions::default().with_linearization(true), ); lw From 2070eb513d85e4b7057b0c6531dc05f30cb3210c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Tue, 16 Dec 2025 14:57:16 +0000 Subject: [PATCH 34/48] last deprecated call --- tket-qsystem/src/replace_bools.rs | 43 +++++++++++++++++-------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/tket-qsystem/src/replace_bools.rs b/tket-qsystem/src/replace_bools.rs index c4db2605b..98c087811 100644 --- a/tket-qsystem/src/replace_bools.rs +++ b/tket-qsystem/src/replace_bools.rs @@ -24,6 +24,7 @@ use hugr::std_extensions::collections::{ use hugr::std_extensions::logic::LogicOp; use hugr::types::{SumType, Term, Type}; use hugr::{Hugr, HugrView, Node, Wire, hugr::hugrmut::HugrMut, type_row}; +use itertools::Itertools; use static_array::{ReplaceStaticArrayBoolPass, ReplaceStaticArrayBoolPassError}; use tket::TketOp; use tket::extension::{ @@ -214,16 +215,7 @@ fn measure_reset_dest() -> NodeTemplate { NodeTemplate::CompoundOp(Box::new(h)) } -fn copy_dfg(ty: Type) -> Hugr { - let mut dfb = DFGBuilder::new(inout_sig(ty.clone(), vec![ty.clone(), ty])).unwrap(); - let mut h = std::mem::take(dfb.hugr_mut()); - let [inp, outp] = h.get_io(h.entrypoint()).unwrap(); - h.connect(inp, 0, outp, 0); - h.connect(inp, 0, outp, 1); - h -} - -fn barray_get_dest(size: u64, elem_ty: Type) -> NodeTemplate { +fn barray_get_dest(rt: &ReplaceTypes, size: u64, elem_ty: Type) -> NodeTemplate { let array_ty = borrow_array_type(size, elem_ty.clone()); let opt_el = option_type(elem_ty.clone()); let mut dfb = DFGBuilder::new(inout_sig( @@ -266,10 +258,25 @@ fn barray_get_dest(size: u64, elem_ty: Type) -> NodeTemplate { ) .unwrap() .outputs_arr(); - let [elem1, elem2] = in_range - .add_hugr_with_wires(copy_dfg(elem_ty.clone()), [elem]) + + let in_range_container = in_range.container_node(); + let copy_discard = rt + .get_linearizer() + .copy_discard_op(&elem_ty, 2) .unwrap() - .outputs_arr(); + .add_hugr(in_range.hugr_mut(), in_range_container) + .unwrap(); + in_range + .hugr_mut() + .connect(elem.node(), elem.source(), copy_discard, 0); + let [elem1, elem2] = in_range + .hugr_mut() + .node_outputs(copy_discard) + .map(|p| Wire::new(copy_discard, p)) + .take(2) + .collect_array() + .unwrap(); + let [arr] = in_range .add_dataflow_op( BArrayUnsafeOpDef::r#return.to_concrete(elem_ty.clone(), size), @@ -405,21 +412,19 @@ fn lowerer() -> ReplaceTypes { ); } - #[expect(deprecated)] // TODO: Replace with set_replace_parametrized_op - lw.replace_parametrized_op_with( + lw.set_replace_parametrized_op( borrow_array::EXTENSION .get_op(GenericArrayOpDef::::get.opdef_id().as_str()) .unwrap(), - |args| { + |args, rt| { let [Term::BoundedNat(size), Term::Runtime(elem_ty)] = args else { unreachable!() }; if elem_ty.copyable() { - return None; + return Ok(None); } - Some(barray_get_dest(*size, elem_ty.clone())) + Ok(Some(barray_get_dest(rt, *size, elem_ty.clone()))) }, - hugr::algorithms::replace_types::ReplacementOptions::default().with_linearization(true), ); lw From 31e23384f330cd12676b5a601221a6651535f02a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Wed, 17 Dec 2025 12:48:00 +0000 Subject: [PATCH 35/48] Update snapshots --- .../measure_qb_array_aarch64-apple-darwin | 126 ++--- .../print_array_aarch64-apple-darwin | 482 ++++++++--------- .../measure_qb_array_x86_64-apple-darwin | 126 ++--- .../print_array_x86_64-apple-darwin | 488 +++++++++--------- .../measure_qb_array_x86_64-unknown-linux-gnu | 126 ++--- .../print_array_x86_64-unknown-linux-gnu | 488 +++++++++--------- .../measure_qb_array_x86_64-windows-msvc | 126 ++--- .../print_array_x86_64-windows-msvc | 488 +++++++++--------- 8 files changed, 1225 insertions(+), 1225 deletions(-) diff --git a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/aarch64-apple-darwin-measure_qb_array/measure_qb_array_aarch64-apple-darwin b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/aarch64-apple-darwin-measure_qb_array/measure_qb_array_aarch64-apple-darwin index 2344ed455..e980f229f 100644 --- a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/aarch64-apple-darwin-measure_qb_array/measure_qb_array_aarch64-apple-darwin +++ b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/aarch64-apple-darwin-measure_qb_array/measure_qb_array_aarch64-apple-darwin @@ -38,8 +38,8 @@ entry: br label %cond_20_case_1.i cond_20_case_1.i: ; preds = %cond_exit_20.i, %entry - %"15_0.sroa.0.0295.i" = phi i64 [ 0, %entry ], [ %5, %cond_exit_20.i ] - %5 = add nuw nsw i64 %"15_0.sroa.0.0295.i", 1 + %"15_0.sroa.0.0294.i" = phi i64 [ 0, %entry ], [ %5, %cond_exit_20.i ] + %5 = add nuw nsw i64 %"15_0.sroa.0.0294.i", 1 %qalloc.i.i = tail call i64 @___qalloc() %not_max.not.i.i = icmp eq i64 %qalloc.i.i, -1 br i1 %not_max.not.i.i, label %id_bb.i.i, label %reset_bb.i.i @@ -59,10 +59,10 @@ cond_217_case_0.i.i: ; preds = %id_bb.i.i unreachable __barray_check_bounds.exit.i: ; preds = %id_bb.i.i - %8 = lshr i64 %"15_0.sroa.0.0295.i", 6 + %8 = lshr i64 %"15_0.sroa.0.0294.i", 6 %9 = getelementptr inbounds i64, i64* %4, i64 %8 %10 = load i64, i64* %9, align 4 - %11 = shl nuw nsw i64 1, %"15_0.sroa.0.0295.i" + %11 = shl nuw nsw i64 1, %"15_0.sroa.0.0294.i" %12 = and i64 %10, %11 %.not.i.i = icmp eq i64 %12, 0 br i1 %.not.i.i, label %panic.i.i, label %cond_exit_20.i @@ -75,7 +75,7 @@ cond_exit_20.i: ; preds = %__barray_check_boun %.fca.1.extract.i.i = extractvalue { i1, i64 } %7, 1 %13 = xor i64 %10, %11 store i64 %13, i64* %9, align 4 - %14 = getelementptr inbounds i64, i64* %2, i64 %"15_0.sroa.0.0295.i" + %14 = getelementptr inbounds i64, i64* %2, i64 %"15_0.sroa.0.0294.i" store i64 %.fca.1.extract.i.i, i64* %14, align 4 %exitcond.not.i = icmp eq i64 %5, 10 br i1 %exitcond.not.i, label %loop_out.i, label %cond_20_case_1.i @@ -83,10 +83,10 @@ cond_exit_20.i: ; preds = %__barray_check_boun loop_out.i: ; preds = %cond_exit_20.i %15 = load i64, i64* %4, align 4 %16 = and i64 %15, 1 - %.not.i259.i = icmp eq i64 %16, 0 - br i1 %.not.i259.i, label %__barray_mask_borrow.exit.i, label %panic.i260.i + %.not.i258.i = icmp eq i64 %16, 0 + br i1 %.not.i258.i, label %__barray_mask_borrow.exit.i, label %panic.i259.i -panic.i260.i: ; preds = %loop_out.i +panic.i259.i: ; preds = %loop_out.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable @@ -97,27 +97,27 @@ __barray_mask_borrow.exit.i: ; preds = %loop_out.i tail call void @___rxy(i64 %18, double 0x400921FB54442D18, double 0.000000e+00) %19 = load i64, i64* %4, align 4 %20 = and i64 %19, 1 - %.not.i261.i = icmp eq i64 %20, 0 - br i1 %.not.i261.i, label %panic.i262.i, label %__barray_mask_return.exit263.i + %.not.i260.i = icmp eq i64 %20, 0 + br i1 %.not.i260.i, label %panic.i261.i, label %__barray_mask_return.exit262.i -panic.i262.i: ; preds = %__barray_mask_borrow.exit.i +panic.i261.i: ; preds = %__barray_mask_borrow.exit.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit263.i: ; preds = %__barray_mask_borrow.exit.i +__barray_mask_return.exit262.i: ; preds = %__barray_mask_borrow.exit.i %21 = xor i64 %19, 1 store i64 %21, i64* %4, align 4 store i64 %18, i64* %2, align 4 %22 = load i64, i64* %4, align 4 %23 = and i64 %22, 4 - %.not.i264.i = icmp eq i64 %23, 0 - br i1 %.not.i264.i, label %__barray_mask_borrow.exit266.i, label %panic.i265.i + %.not.i263.i = icmp eq i64 %23, 0 + br i1 %.not.i263.i, label %__barray_mask_borrow.exit265.i, label %panic.i264.i -panic.i265.i: ; preds = %__barray_mask_return.exit263.i +panic.i264.i: ; preds = %__barray_mask_return.exit262.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit266.i: ; preds = %__barray_mask_return.exit263.i +__barray_mask_borrow.exit265.i: ; preds = %__barray_mask_return.exit262.i %24 = xor i64 %22, 4 store i64 %24, i64* %4, align 4 %25 = getelementptr inbounds i8, i8* %1, i64 16 @@ -126,27 +126,27 @@ __barray_mask_borrow.exit266.i: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %27, double 0x400921FB54442D18, double 0.000000e+00) %28 = load i64, i64* %4, align 4 %29 = and i64 %28, 4 - %.not.i267.i = icmp eq i64 %29, 0 - br i1 %.not.i267.i, label %panic.i268.i, label %__barray_mask_return.exit269.i + %.not.i266.i = icmp eq i64 %29, 0 + br i1 %.not.i266.i, label %panic.i267.i, label %__barray_mask_return.exit268.i -panic.i268.i: ; preds = %__barray_mask_borrow.exit266.i +panic.i267.i: ; preds = %__barray_mask_borrow.exit265.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit269.i: ; preds = %__barray_mask_borrow.exit266.i +__barray_mask_return.exit268.i: ; preds = %__barray_mask_borrow.exit265.i %30 = xor i64 %28, 4 store i64 %30, i64* %4, align 4 store i64 %27, i64* %26, align 4 %31 = load i64, i64* %4, align 4 %32 = and i64 %31, 8 - %.not.i270.i = icmp eq i64 %32, 0 - br i1 %.not.i270.i, label %__barray_mask_borrow.exit272.i, label %panic.i271.i + %.not.i269.i = icmp eq i64 %32, 0 + br i1 %.not.i269.i, label %__barray_mask_borrow.exit271.i, label %panic.i270.i -panic.i271.i: ; preds = %__barray_mask_return.exit269.i +panic.i270.i: ; preds = %__barray_mask_return.exit268.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit272.i: ; preds = %__barray_mask_return.exit269.i +__barray_mask_borrow.exit271.i: ; preds = %__barray_mask_return.exit268.i %33 = xor i64 %31, 8 store i64 %33, i64* %4, align 4 %34 = getelementptr inbounds i8, i8* %1, i64 24 @@ -155,27 +155,27 @@ __barray_mask_borrow.exit272.i: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %36, double 0x400921FB54442D18, double 0.000000e+00) %37 = load i64, i64* %4, align 4 %38 = and i64 %37, 8 - %.not.i273.i = icmp eq i64 %38, 0 - br i1 %.not.i273.i, label %panic.i274.i, label %__barray_mask_return.exit275.i + %.not.i272.i = icmp eq i64 %38, 0 + br i1 %.not.i272.i, label %panic.i273.i, label %__barray_mask_return.exit274.i -panic.i274.i: ; preds = %__barray_mask_borrow.exit272.i +panic.i273.i: ; preds = %__barray_mask_borrow.exit271.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit275.i: ; preds = %__barray_mask_borrow.exit272.i +__barray_mask_return.exit274.i: ; preds = %__barray_mask_borrow.exit271.i %39 = xor i64 %37, 8 store i64 %39, i64* %4, align 4 store i64 %36, i64* %35, align 4 %40 = load i64, i64* %4, align 4 %41 = and i64 %40, 512 - %.not.i276.i = icmp eq i64 %41, 0 - br i1 %.not.i276.i, label %__barray_mask_borrow.exit278.i, label %panic.i277.i + %.not.i275.i = icmp eq i64 %41, 0 + br i1 %.not.i275.i, label %__barray_mask_borrow.exit277.i, label %panic.i276.i -panic.i277.i: ; preds = %__barray_mask_return.exit275.i +panic.i276.i: ; preds = %__barray_mask_return.exit274.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit278.i: ; preds = %__barray_mask_return.exit275.i +__barray_mask_borrow.exit277.i: ; preds = %__barray_mask_return.exit274.i %42 = xor i64 %40, 512 store i64 %42, i64* %4, align 4 %43 = getelementptr inbounds i8, i8* %1, i64 72 @@ -184,14 +184,14 @@ __barray_mask_borrow.exit278.i: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %45, double 0x400921FB54442D18, double 0.000000e+00) %46 = load i64, i64* %4, align 4 %47 = and i64 %46, 512 - %.not.i279.i = icmp eq i64 %47, 0 - br i1 %.not.i279.i, label %panic.i280.i, label %__barray_mask_return.exit281.i + %.not.i278.i = icmp eq i64 %47, 0 + br i1 %.not.i278.i, label %panic.i279.i, label %__barray_mask_return.exit280.i -panic.i280.i: ; preds = %__barray_mask_borrow.exit278.i +panic.i279.i: ; preds = %__barray_mask_borrow.exit277.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit281.i: ; preds = %__barray_mask_borrow.exit278.i +__barray_mask_return.exit280.i: ; preds = %__barray_mask_borrow.exit277.i %48 = xor i64 %46, 512 store i64 %48, i64* %4, align 4 store i64 %45, i64* %44, align 4 @@ -212,19 +212,19 @@ mask_block_ok.i.i.i.i: ; preds = %cond_exit_353.i.i "__hugr__.$measure_array$$n(10).277.exit.i": ; preds = %mask_block_ok.i.i.i.i tail call void @heap_free(i8* nonnull %1) tail call void @heap_free(i8* nonnull %3) - br label %__barray_check_bounds.exit284.i + br label %__barray_check_bounds.exit283.i mask_block_err.i.i.i.i: ; preds = %mask_block_ok.i.i.i.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -56: ; preds = %cond_exit_353.i.i, %__barray_mask_return.exit281.i - %"303_0.sroa.15.0.i297.i" = phi i64 [ 0, %__barray_mask_return.exit281.i ], [ %57, %cond_exit_353.i.i ] - %57 = add nuw nsw i64 %"303_0.sroa.15.0.i297.i", 1 - %58 = lshr i64 %"303_0.sroa.15.0.i297.i", 6 +56: ; preds = %cond_exit_353.i.i, %__barray_mask_return.exit280.i + %"303_0.sroa.15.0.i296.i" = phi i64 [ 0, %__barray_mask_return.exit280.i ], [ %57, %cond_exit_353.i.i ] + %57 = add nuw nsw i64 %"303_0.sroa.15.0.i296.i", 1 + %58 = lshr i64 %"303_0.sroa.15.0.i296.i", 6 %59 = getelementptr inbounds i64, i64* %4, i64 %58 %60 = load i64, i64* %59, align 4 - %61 = shl nuw nsw i64 1, %"303_0.sroa.15.0.i297.i" + %61 = shl nuw nsw i64 1, %"303_0.sroa.15.0.i296.i" %62 = and i64 %60, %61 %.not.i99.i.i.i = icmp eq i64 %62, 0 br i1 %.not.i99.i.i.i, label %__barray_check_bounds.exit.i.i, label %panic.i.i.i.i @@ -236,7 +236,7 @@ panic.i.i.i.i: ; preds = %56 __barray_check_bounds.exit.i.i: ; preds = %56 %63 = xor i64 %60, %61 store i64 %63, i64* %59, align 4 - %64 = getelementptr inbounds i64, i64* %2, i64 %"303_0.sroa.15.0.i297.i" + %64 = getelementptr inbounds i64, i64* %2, i64 %"303_0.sroa.15.0.i296.i" %65 = load i64, i64* %64, align 4 %lazy_measure.i.i = tail call i64 @___lazy_measure(i64 %65) tail call void @___qfree(i64 %65) @@ -254,51 +254,51 @@ cond_exit_353.i.i: ; preds = %__barray_check_boun %"367_054.fca.1.insert.i.i" = insertvalue { i1, i64, i1 } { i1 true, i64 poison, i1 poison }, i64 %lazy_measure.i.i, 1 %69 = xor i64 %67, %61 store i64 %69, i64* %66, align 4 - %70 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"303_0.sroa.15.0.i297.i" + %70 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"303_0.sroa.15.0.i296.i" store { i1, i64, i1 } %"367_054.fca.1.insert.i.i", { i1, i64, i1 }* %70, align 4 - %exitcond298.not.i = icmp eq i64 %57, 10 - br i1 %exitcond298.not.i, label %mask_block_ok.i.i.i.i, label %56 + %exitcond297.not.i = icmp eq i64 %57, 10 + br i1 %exitcond297.not.i, label %mask_block_ok.i.i.i.i, label %56 -cond_160_case_0.i: ; preds = %cond_exit_160.i +cond_187_case_0.i: ; preds = %cond_exit_187.i %71 = load i64, i64* %52, align 4 %72 = or i64 %71, -1024 store i64 %72, i64* %52, align 4 %73 = icmp eq i64 %72, -1 br i1 %73, label %__hugr__.main.1.exit, label %mask_block_err.i.i -mask_block_err.i.i: ; preds = %cond_160_case_0.i +mask_block_err.i.i: ; preds = %cond_187_case_0.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit284.i: ; preds = %"__hugr__.$measure_array$$n(10).277.exit.i", %cond_exit_160.i - %"162_0.0.i1" = phi i64 [ 0, %"__hugr__.$measure_array$$n(10).277.exit.i" ], [ %82, %cond_exit_160.i ] - %74 = lshr i64 %"162_0.0.i1", 6 +__barray_check_bounds.exit283.i: ; preds = %"__hugr__.$measure_array$$n(10).277.exit.i", %cond_exit_187.i + %"164_0.0.i1" = phi i64 [ 0, %"__hugr__.$measure_array$$n(10).277.exit.i" ], [ %82, %cond_exit_187.i ] + %74 = lshr i64 %"164_0.0.i1", 6 %75 = getelementptr inbounds i64, i64* %52, i64 %74 %76 = load i64, i64* %75, align 4 - %77 = shl nuw nsw i64 1, %"162_0.0.i1" + %77 = shl nuw nsw i64 1, %"164_0.0.i1" %78 = and i64 %76, %77 %.not.i = icmp eq i64 %78, 0 - br i1 %.not.i, label %__barray_mask_borrow.exit289.i, label %cond_exit_160.i + br i1 %.not.i, label %__barray_mask_borrow.exit288.i, label %cond_exit_187.i -__barray_mask_borrow.exit289.i: ; preds = %__barray_check_bounds.exit284.i +__barray_mask_borrow.exit288.i: ; preds = %__barray_check_bounds.exit283.i %79 = xor i64 %76, %77 store i64 %79, i64* %75, align 4 - %80 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"162_0.0.i1" + %80 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"164_0.0.i1" %81 = load { i1, i64, i1 }, { i1, i64, i1 }* %80, align 4 - %.fca.0.extract180.i = extractvalue { i1, i64, i1 } %81, 0 - br i1 %.fca.0.extract180.i, label %cond_85_case_1.i, label %cond_exit_160.i + %.fca.0.extract179.i = extractvalue { i1, i64, i1 } %81, 0 + br i1 %.fca.0.extract179.i, label %cond_87_case_1.i, label %cond_exit_187.i -cond_exit_160.i: ; preds = %cond_85_case_1.i, %__barray_mask_borrow.exit289.i, %__barray_check_bounds.exit284.i - %82 = add nuw nsw i64 %"162_0.0.i1", 1 +cond_exit_187.i: ; preds = %cond_87_case_1.i, %__barray_mask_borrow.exit288.i, %__barray_check_bounds.exit283.i + %82 = add nuw nsw i64 %"164_0.0.i1", 1 %exitcond.not = icmp eq i64 %82, 10 - br i1 %exitcond.not, label %cond_160_case_0.i, label %__barray_check_bounds.exit284.i + br i1 %exitcond.not, label %cond_187_case_0.i, label %__barray_check_bounds.exit283.i -cond_85_case_1.i: ; preds = %__barray_mask_borrow.exit289.i +cond_87_case_1.i: ; preds = %__barray_mask_borrow.exit288.i %.fca.1.extract.i = extractvalue { i1, i64, i1 } %81, 1 tail call void @___dec_future_refcount(i64 %.fca.1.extract.i) - br label %cond_exit_160.i + br label %cond_exit_187.i -__hugr__.main.1.exit: ; preds = %cond_160_case_0.i +__hugr__.main.1.exit: ; preds = %cond_187_case_0.i tail call void @heap_free(i8* %49) tail call void @heap_free(i8* nonnull %51) %83 = tail call i64 @teardown() diff --git a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/aarch64-apple-darwin-print_array/print_array_aarch64-apple-darwin b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/aarch64-apple-darwin-print_array/print_array_aarch64-apple-darwin index 249b6f6ad..d13b5e031 100644 --- a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/aarch64-apple-darwin-print_array/print_array_aarch64-apple-darwin +++ b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/aarch64-apple-darwin-print_array/print_array_aarch64-apple-darwin @@ -34,8 +34,8 @@ alloca_block: br label %cond_20_case_1 cond_20_case_1: ; preds = %alloca_block, %cond_exit_20 - %"15_0.sroa.0.0961" = phi i64 [ 0, %alloca_block ], [ %12, %cond_exit_20 ] - %12 = add nuw nsw i64 %"15_0.sroa.0.0961", 1 + %"15_0.sroa.0.0955" = phi i64 [ 0, %alloca_block ], [ %12, %cond_exit_20 ] + %12 = add nuw nsw i64 %"15_0.sroa.0.0955", 1 %qalloc.i = tail call i64 @___qalloc() %not_max.not.i = icmp eq i64 %qalloc.i, -1 br i1 %not_max.not.i, label %id_bb.i, label %reset_bb.i @@ -55,10 +55,10 @@ cond_303_case_0.i: ; preds = %id_bb.i unreachable __barray_check_bounds.exit: ; preds = %id_bb.i - %15 = lshr i64 %"15_0.sroa.0.0961", 6 + %15 = lshr i64 %"15_0.sroa.0.0955", 6 %16 = getelementptr inbounds i64, i64* %11, i64 %15 %17 = load i64, i64* %16, align 4 - %18 = shl nuw nsw i64 1, %"15_0.sroa.0.0961" + %18 = shl nuw nsw i64 1, %"15_0.sroa.0.0955" %19 = and i64 %17, %18 %.not.i = icmp eq i64 %19, 0 br i1 %.not.i, label %panic.i, label %cond_exit_20 @@ -71,7 +71,7 @@ cond_exit_20: ; preds = %__barray_check_boun %.fca.1.extract.i = extractvalue { i1, i64 } %14, 1 %20 = xor i64 %17, %18 store i64 %20, i64* %16, align 4 - %21 = getelementptr inbounds i64, i64* %9, i64 %"15_0.sroa.0.0961" + %21 = getelementptr inbounds i64, i64* %9, i64 %"15_0.sroa.0.0955" store i64 %.fca.1.extract.i, i64* %21, align 4 %exitcond.not = icmp eq i64 %12, 10 br i1 %exitcond.not, label %loop_out, label %cond_20_case_1 @@ -79,10 +79,10 @@ cond_exit_20: ; preds = %__barray_check_boun loop_out: ; preds = %cond_exit_20 %22 = load i64, i64* %11, align 4 %23 = and i64 %22, 1 - %.not.i852 = icmp eq i64 %23, 0 - br i1 %.not.i852, label %__barray_mask_borrow.exit, label %panic.i853 + %.not.i846 = icmp eq i64 %23, 0 + br i1 %.not.i846, label %__barray_mask_borrow.exit, label %panic.i847 -panic.i853: ; preds = %loop_out +panic.i847: ; preds = %loop_out tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable @@ -93,27 +93,27 @@ __barray_mask_borrow.exit: ; preds = %loop_out tail call void @___rxy(i64 %25, double 0x400921FB54442D18, double 0.000000e+00) %26 = load i64, i64* %11, align 4 %27 = and i64 %26, 1 - %.not.i854 = icmp eq i64 %27, 0 - br i1 %.not.i854, label %panic.i855, label %__barray_mask_return.exit856 + %.not.i848 = icmp eq i64 %27, 0 + br i1 %.not.i848, label %panic.i849, label %__barray_mask_return.exit850 -panic.i855: ; preds = %__barray_mask_borrow.exit +panic.i849: ; preds = %__barray_mask_borrow.exit tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit856: ; preds = %__barray_mask_borrow.exit +__barray_mask_return.exit850: ; preds = %__barray_mask_borrow.exit %28 = xor i64 %26, 1 store i64 %28, i64* %11, align 4 store i64 %25, i64* %9, align 4 %29 = load i64, i64* %11, align 4 %30 = and i64 %29, 4 - %.not.i857 = icmp eq i64 %30, 0 - br i1 %.not.i857, label %__barray_mask_borrow.exit859, label %panic.i858 + %.not.i851 = icmp eq i64 %30, 0 + br i1 %.not.i851, label %__barray_mask_borrow.exit853, label %panic.i852 -panic.i858: ; preds = %__barray_mask_return.exit856 +panic.i852: ; preds = %__barray_mask_return.exit850 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit859: ; preds = %__barray_mask_return.exit856 +__barray_mask_borrow.exit853: ; preds = %__barray_mask_return.exit850 %31 = xor i64 %29, 4 store i64 %31, i64* %11, align 4 %32 = getelementptr inbounds i8, i8* %8, i64 16 @@ -122,27 +122,27 @@ __barray_mask_borrow.exit859: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %34, double 0x400921FB54442D18, double 0.000000e+00) %35 = load i64, i64* %11, align 4 %36 = and i64 %35, 4 - %.not.i860 = icmp eq i64 %36, 0 - br i1 %.not.i860, label %panic.i861, label %__barray_mask_return.exit862 + %.not.i854 = icmp eq i64 %36, 0 + br i1 %.not.i854, label %panic.i855, label %__barray_mask_return.exit856 -panic.i861: ; preds = %__barray_mask_borrow.exit859 +panic.i855: ; preds = %__barray_mask_borrow.exit853 tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit862: ; preds = %__barray_mask_borrow.exit859 +__barray_mask_return.exit856: ; preds = %__barray_mask_borrow.exit853 %37 = xor i64 %35, 4 store i64 %37, i64* %11, align 4 store i64 %34, i64* %33, align 4 %38 = load i64, i64* %11, align 4 %39 = and i64 %38, 8 - %.not.i863 = icmp eq i64 %39, 0 - br i1 %.not.i863, label %__barray_mask_borrow.exit865, label %panic.i864 + %.not.i857 = icmp eq i64 %39, 0 + br i1 %.not.i857, label %__barray_mask_borrow.exit859, label %panic.i858 -panic.i864: ; preds = %__barray_mask_return.exit862 +panic.i858: ; preds = %__barray_mask_return.exit856 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit865: ; preds = %__barray_mask_return.exit862 +__barray_mask_borrow.exit859: ; preds = %__barray_mask_return.exit856 %40 = xor i64 %38, 8 store i64 %40, i64* %11, align 4 %41 = getelementptr inbounds i8, i8* %8, i64 24 @@ -151,27 +151,27 @@ __barray_mask_borrow.exit865: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %43, double 0x400921FB54442D18, double 0.000000e+00) %44 = load i64, i64* %11, align 4 %45 = and i64 %44, 8 - %.not.i866 = icmp eq i64 %45, 0 - br i1 %.not.i866, label %panic.i867, label %__barray_mask_return.exit868 + %.not.i860 = icmp eq i64 %45, 0 + br i1 %.not.i860, label %panic.i861, label %__barray_mask_return.exit862 -panic.i867: ; preds = %__barray_mask_borrow.exit865 +panic.i861: ; preds = %__barray_mask_borrow.exit859 tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit868: ; preds = %__barray_mask_borrow.exit865 +__barray_mask_return.exit862: ; preds = %__barray_mask_borrow.exit859 %46 = xor i64 %44, 8 store i64 %46, i64* %11, align 4 store i64 %43, i64* %42, align 4 %47 = load i64, i64* %11, align 4 %48 = and i64 %47, 512 - %.not.i869 = icmp eq i64 %48, 0 - br i1 %.not.i869, label %__barray_mask_borrow.exit871, label %panic.i870 + %.not.i863 = icmp eq i64 %48, 0 + br i1 %.not.i863, label %__barray_mask_borrow.exit865, label %panic.i864 -panic.i870: ; preds = %__barray_mask_return.exit868 +panic.i864: ; preds = %__barray_mask_return.exit862 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit871: ; preds = %__barray_mask_return.exit868 +__barray_mask_borrow.exit865: ; preds = %__barray_mask_return.exit862 %49 = xor i64 %47, 512 store i64 %49, i64* %11, align 4 %50 = getelementptr inbounds i8, i8* %8, i64 72 @@ -180,14 +180,14 @@ __barray_mask_borrow.exit871: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %52, double 0x400921FB54442D18, double 0.000000e+00) %53 = load i64, i64* %11, align 4 %54 = and i64 %53, 512 - %.not.i872 = icmp eq i64 %54, 0 - br i1 %.not.i872, label %panic.i873, label %__barray_mask_return.exit874 + %.not.i866 = icmp eq i64 %54, 0 + br i1 %.not.i866, label %panic.i867, label %__barray_mask_return.exit868 -panic.i873: ; preds = %__barray_mask_borrow.exit871 +panic.i867: ; preds = %__barray_mask_borrow.exit865 tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit874: ; preds = %__barray_mask_borrow.exit871 +__barray_mask_return.exit868: ; preds = %__barray_mask_borrow.exit865 %55 = xor i64 %53, 512 store i64 %55, i64* %11, align 4 store i64 %52, i64* %51, align 4 @@ -223,13 +223,13 @@ mask_block_err.i.i.i: ; preds = %mask_block_ok.i.i.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -69: ; preds = %__barray_mask_return.exit874, %cond_exit_443.i - %"393_0.sroa.15.0.i963" = phi i64 [ 0, %__barray_mask_return.exit874 ], [ %70, %cond_exit_443.i ] - %70 = add nuw nsw i64 %"393_0.sroa.15.0.i963", 1 - %71 = lshr i64 %"393_0.sroa.15.0.i963", 6 +69: ; preds = %__barray_mask_return.exit868, %cond_exit_443.i + %"393_0.sroa.15.0.i957" = phi i64 [ 0, %__barray_mask_return.exit868 ], [ %70, %cond_exit_443.i ] + %70 = add nuw nsw i64 %"393_0.sroa.15.0.i957", 1 + %71 = lshr i64 %"393_0.sroa.15.0.i957", 6 %72 = getelementptr inbounds i64, i64* %11, i64 %71 %73 = load i64, i64* %72, align 4 - %74 = shl nuw nsw i64 1, %"393_0.sroa.15.0.i963" + %74 = shl nuw nsw i64 1, %"393_0.sroa.15.0.i957" %75 = and i64 %73, %74 %.not.i99.i.i = icmp eq i64 %75, 0 br i1 %.not.i99.i.i, label %__barray_check_bounds.exit.i, label %panic.i.i.i @@ -241,7 +241,7 @@ panic.i.i.i: ; preds = %69 __barray_check_bounds.exit.i: ; preds = %69 %76 = xor i64 %73, %74 store i64 %76, i64* %72, align 4 - %77 = getelementptr inbounds i64, i64* %9, i64 %"393_0.sroa.15.0.i963" + %77 = getelementptr inbounds i64, i64* %9, i64 %"393_0.sroa.15.0.i957" %78 = load i64, i64* %77, align 4 %lazy_measure.i = tail call i64 @___lazy_measure(i64 %78) tail call void @___qfree(i64 %78) @@ -259,10 +259,10 @@ cond_exit_443.i: ; preds = %__barray_check_boun %"457_054.fca.1.insert.i" = insertvalue { i1, i64, i1 } { i1 true, i64 poison, i1 poison }, i64 %lazy_measure.i, 1 %82 = xor i64 %80, %74 store i64 %82, i64* %79, align 4 - %83 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %"393_0.sroa.15.0.i963" + %83 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %"393_0.sroa.15.0.i957" store { i1, i64, i1 } %"457_054.fca.1.insert.i", { i1, i64, i1 }* %83, align 4 - %exitcond979.not = icmp eq i64 %70, 10 - br i1 %exitcond979.not, label %mask_block_ok.i.i.i, label %69 + %exitcond973.not = icmp eq i64 %70, 10 + br i1 %exitcond973.not, label %mask_block_ok.i.i.i, label %69 __barray_check_none_borrowed.exit: ; preds = %"__hugr__.$measure_array$$n(10).367.exit" %84 = tail call i8* @heap_alloc(i64 240) @@ -277,79 +277,79 @@ mask_block_err.i: ; preds = %"__hugr__.$measure_ tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -89: ; preds = %__barray_check_none_borrowed.exit, %__hugr__.const_fun_290.309.exit - %storemerge850968 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %107, %__hugr__.const_fun_290.309.exit ] - %90 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %105, %__hugr__.const_fun_290.309.exit ] - %91 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %storemerge850968 +89: ; preds = %__barray_check_none_borrowed.exit, %__hugr__.const_fun_338.322.exit + %storemerge844962 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %107, %__hugr__.const_fun_338.322.exit ] + %90 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %105, %__hugr__.const_fun_338.322.exit ] + %91 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %storemerge844962 %92 = load { i1, i64, i1 }, { i1, i64, i1 }* %91, align 4 %.fca.0.extract118.i = extractvalue { i1, i64, i1 } %92, 0 %.fca.1.extract119.i = extractvalue { i1, i64, i1 } %92, 1 - br i1 %.fca.0.extract118.i, label %cond_525_case_1.i, label %cond_exit_525.i + br i1 %.fca.0.extract118.i, label %cond_513_case_1.i, label %cond_exit_513.i -cond_525_case_1.i: ; preds = %89 +cond_513_case_1.i: ; preds = %89 tail call void @___inc_future_refcount(i64 %.fca.1.extract119.i) %93 = insertvalue { i1, i64, i1 } { i1 true, i64 poison, i1 poison }, i64 %.fca.1.extract119.i, 1 - br label %cond_exit_525.i + br label %cond_exit_513.i -cond_exit_525.i: ; preds = %cond_525_case_1.i, %89 - %.pn.i = phi { i1, i64, i1 } [ %93, %cond_525_case_1.i ], [ %92, %89 ] +cond_exit_513.i: ; preds = %cond_513_case_1.i, %89 + %.pn.i = phi { i1, i64, i1 } [ %93, %cond_513_case_1.i ], [ %92, %89 ] %"04.sroa.6.0.i" = extractvalue { i1, i64, i1 } %.pn.i, 2 - %exitcond980.not = icmp eq i64 %storemerge850968, 10 - br i1 %exitcond980.not, label %cond_528_case_0.i, label %94 + %exitcond974.not = icmp eq i64 %storemerge844962, 10 + br i1 %exitcond974.not, label %cond_516_case_0.i, label %94 -94: ; preds = %cond_exit_525.i +94: ; preds = %cond_exit_513.i %95 = lshr i64 %90, 6 %96 = getelementptr inbounds i64, i64* %65, i64 %95 %97 = load i64, i64* %96, align 4 %98 = and i64 %90, 63 %99 = shl nuw i64 1, %98 %100 = and i64 %97, %99 - %.not.i.i876 = icmp eq i64 %100, 0 - br i1 %.not.i.i876, label %cond_528_case_1.i, label %panic.i.i877 + %.not.i.i870 = icmp eq i64 %100, 0 + br i1 %.not.i.i870, label %cond_516_case_1.i, label %panic.i.i871 -panic.i.i877: ; preds = %94 +panic.i.i871: ; preds = %94 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -cond_528_case_0.i: ; preds = %cond_exit_525.i +cond_516_case_0.i: ; preds = %cond_exit_513.i tail call void @panic(i32 1001, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @"e_Expected v.E6312129.0", i64 0, i64 0)) unreachable -cond_528_case_1.i: ; preds = %94 +cond_516_case_1.i: ; preds = %94 %"17.fca.2.insert.i" = insertvalue { i1, i64, i1 } %92, i1 %"04.sroa.6.0.i", 2 %101 = insertvalue { i1, { i1, i64, i1 } } { i1 true, { i1, i64, i1 } poison }, { i1, i64, i1 } %"17.fca.2.insert.i", 1 %102 = getelementptr inbounds { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %88, i64 %90 %103 = getelementptr inbounds { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %102, i64 0, i32 0 %104 = load i1, i1* %103, align 1 store { i1, { i1, i64, i1 } } %101, { i1, { i1, i64, i1 } }* %102, align 4 - br i1 %104, label %cond_529_case_1.i, label %__hugr__.const_fun_290.309.exit + br i1 %104, label %cond_517_case_1.i, label %__hugr__.const_fun_338.322.exit -cond_529_case_1.i: ; preds = %cond_528_case_1.i +cond_517_case_1.i: ; preds = %cond_516_case_1.i tail call void @panic(i32 1001, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @"e_Expected v.2F17E0A9.0", i64 0, i64 0)) unreachable -__hugr__.const_fun_290.309.exit: ; preds = %cond_528_case_1.i +__hugr__.const_fun_338.322.exit: ; preds = %cond_516_case_1.i %105 = add nuw nsw i64 %90, 1 - %106 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %85, i64 %storemerge850968 + %106 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %85, i64 %storemerge844962 store { i1, i64, i1 } %"17.fca.2.insert.i", { i1, i64, i1 }* %106, align 4 - %107 = add nuw nsw i64 %storemerge850968, 1 - %exitcond981.not = icmp eq i64 %107, 10 - br i1 %exitcond981.not, label %mask_block_ok.i881, label %89 + %107 = add nuw nsw i64 %storemerge844962, 1 + %exitcond975.not = icmp eq i64 %107, 10 + br i1 %exitcond975.not, label %mask_block_ok.i875, label %89 -mask_block_ok.i881: ; preds = %__hugr__.const_fun_290.309.exit +mask_block_ok.i875: ; preds = %__hugr__.const_fun_338.322.exit tail call void @heap_free(i8* nonnull %56) tail call void @heap_free(i8* %58) %108 = load i64, i64* %65, align 4 %109 = and i64 %108, 1023 store i64 %109, i64* %65, align 4 %110 = icmp eq i64 %109, 0 - br i1 %110, label %__barray_check_none_borrowed.exit883, label %mask_block_err.i882 + br i1 %110, label %__barray_check_none_borrowed.exit877, label %mask_block_err.i876 -mask_block_err.i882: ; preds = %mask_block_ok.i881 +mask_block_err.i876: ; preds = %mask_block_ok.i875 tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_none_borrowed.exit883: ; preds = %mask_block_ok.i881 +__barray_check_none_borrowed.exit877: ; preds = %mask_block_ok.i875 %111 = tail call i8* @heap_alloc(i64 240) %112 = bitcast i8* %111 to { i1, i64, i1 }* %113 = tail call i8* @heap_alloc(i64 8) @@ -357,22 +357,22 @@ __barray_check_none_borrowed.exit883: ; preds = %mask_block_ok.i881 store i64 0, i64* %114, align 1 %115 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %88, align 4 %.fca.0.extract11.i = extractvalue { i1, { i1, i64, i1 } } %115, 0 - br i1 %.fca.0.extract11.i, label %__hugr__.const_fun_284.290.exit, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i, label %__hugr__.const_fun_287.338.exit, label %cond_558_case_0.i -cond_570_case_0.i: ; preds = %__hugr__.const_fun_284.290.exit.8, %__hugr__.const_fun_284.290.exit.7, %__hugr__.const_fun_284.290.exit.6, %__hugr__.const_fun_284.290.exit.5, %__hugr__.const_fun_284.290.exit.4, %__hugr__.const_fun_284.290.exit.3, %__hugr__.const_fun_284.290.exit.2, %__hugr__.const_fun_284.290.exit.1, %__hugr__.const_fun_284.290.exit, %__barray_check_none_borrowed.exit883 +cond_558_case_0.i: ; preds = %__hugr__.const_fun_287.338.exit.8, %__hugr__.const_fun_287.338.exit.7, %__hugr__.const_fun_287.338.exit.6, %__hugr__.const_fun_287.338.exit.5, %__hugr__.const_fun_287.338.exit.4, %__hugr__.const_fun_287.338.exit.3, %__hugr__.const_fun_287.338.exit.2, %__hugr__.const_fun_287.338.exit.1, %__hugr__.const_fun_287.338.exit, %__barray_check_none_borrowed.exit877 tail call void @panic(i32 1001, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @"e_Expected v.E6312129.0", i64 0, i64 0)) unreachable -__hugr__.const_fun_284.290.exit: ; preds = %__barray_check_none_borrowed.exit883 +__hugr__.const_fun_287.338.exit: ; preds = %__barray_check_none_borrowed.exit877 %116 = extractvalue { i1, { i1, i64, i1 } } %115, 1 store { i1, i64, i1 } %116, { i1, i64, i1 }* %112, align 4 %117 = getelementptr inbounds i8, i8* %63, i64 32 %118 = bitcast i8* %117 to { i1, { i1, i64, i1 } }* %119 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %118, align 4 %.fca.0.extract11.i.1 = extractvalue { i1, { i1, i64, i1 } } %119, 0 - br i1 %.fca.0.extract11.i.1, label %__hugr__.const_fun_284.290.exit.1, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.1, label %__hugr__.const_fun_287.338.exit.1, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.1: ; preds = %__hugr__.const_fun_284.290.exit +__hugr__.const_fun_287.338.exit.1: ; preds = %__hugr__.const_fun_287.338.exit %120 = extractvalue { i1, { i1, i64, i1 } } %119, 1 %121 = getelementptr inbounds i8, i8* %111, i64 24 %122 = bitcast i8* %121 to { i1, i64, i1 }* @@ -381,9 +381,9 @@ __hugr__.const_fun_284.290.exit.1: ; preds = %__hugr__.const_fun_ %124 = bitcast i8* %123 to { i1, { i1, i64, i1 } }* %125 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %124, align 4 %.fca.0.extract11.i.2 = extractvalue { i1, { i1, i64, i1 } } %125, 0 - br i1 %.fca.0.extract11.i.2, label %__hugr__.const_fun_284.290.exit.2, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.2, label %__hugr__.const_fun_287.338.exit.2, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.2: ; preds = %__hugr__.const_fun_284.290.exit.1 +__hugr__.const_fun_287.338.exit.2: ; preds = %__hugr__.const_fun_287.338.exit.1 %126 = extractvalue { i1, { i1, i64, i1 } } %125, 1 %127 = getelementptr inbounds i8, i8* %111, i64 48 %128 = bitcast i8* %127 to { i1, i64, i1 }* @@ -392,9 +392,9 @@ __hugr__.const_fun_284.290.exit.2: ; preds = %__hugr__.const_fun_ %130 = bitcast i8* %129 to { i1, { i1, i64, i1 } }* %131 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %130, align 4 %.fca.0.extract11.i.3 = extractvalue { i1, { i1, i64, i1 } } %131, 0 - br i1 %.fca.0.extract11.i.3, label %__hugr__.const_fun_284.290.exit.3, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.3, label %__hugr__.const_fun_287.338.exit.3, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.3: ; preds = %__hugr__.const_fun_284.290.exit.2 +__hugr__.const_fun_287.338.exit.3: ; preds = %__hugr__.const_fun_287.338.exit.2 %132 = extractvalue { i1, { i1, i64, i1 } } %131, 1 %133 = getelementptr inbounds i8, i8* %111, i64 72 %134 = bitcast i8* %133 to { i1, i64, i1 }* @@ -403,9 +403,9 @@ __hugr__.const_fun_284.290.exit.3: ; preds = %__hugr__.const_fun_ %136 = bitcast i8* %135 to { i1, { i1, i64, i1 } }* %137 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %136, align 4 %.fca.0.extract11.i.4 = extractvalue { i1, { i1, i64, i1 } } %137, 0 - br i1 %.fca.0.extract11.i.4, label %__hugr__.const_fun_284.290.exit.4, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.4, label %__hugr__.const_fun_287.338.exit.4, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.4: ; preds = %__hugr__.const_fun_284.290.exit.3 +__hugr__.const_fun_287.338.exit.4: ; preds = %__hugr__.const_fun_287.338.exit.3 %138 = extractvalue { i1, { i1, i64, i1 } } %137, 1 %139 = getelementptr inbounds i8, i8* %111, i64 96 %140 = bitcast i8* %139 to { i1, i64, i1 }* @@ -414,9 +414,9 @@ __hugr__.const_fun_284.290.exit.4: ; preds = %__hugr__.const_fun_ %142 = bitcast i8* %141 to { i1, { i1, i64, i1 } }* %143 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %142, align 4 %.fca.0.extract11.i.5 = extractvalue { i1, { i1, i64, i1 } } %143, 0 - br i1 %.fca.0.extract11.i.5, label %__hugr__.const_fun_284.290.exit.5, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.5, label %__hugr__.const_fun_287.338.exit.5, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.5: ; preds = %__hugr__.const_fun_284.290.exit.4 +__hugr__.const_fun_287.338.exit.5: ; preds = %__hugr__.const_fun_287.338.exit.4 %144 = extractvalue { i1, { i1, i64, i1 } } %143, 1 %145 = getelementptr inbounds i8, i8* %111, i64 120 %146 = bitcast i8* %145 to { i1, i64, i1 }* @@ -425,9 +425,9 @@ __hugr__.const_fun_284.290.exit.5: ; preds = %__hugr__.const_fun_ %148 = bitcast i8* %147 to { i1, { i1, i64, i1 } }* %149 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %148, align 4 %.fca.0.extract11.i.6 = extractvalue { i1, { i1, i64, i1 } } %149, 0 - br i1 %.fca.0.extract11.i.6, label %__hugr__.const_fun_284.290.exit.6, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.6, label %__hugr__.const_fun_287.338.exit.6, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.6: ; preds = %__hugr__.const_fun_284.290.exit.5 +__hugr__.const_fun_287.338.exit.6: ; preds = %__hugr__.const_fun_287.338.exit.5 %150 = extractvalue { i1, { i1, i64, i1 } } %149, 1 %151 = getelementptr inbounds i8, i8* %111, i64 144 %152 = bitcast i8* %151 to { i1, i64, i1 }* @@ -436,9 +436,9 @@ __hugr__.const_fun_284.290.exit.6: ; preds = %__hugr__.const_fun_ %154 = bitcast i8* %153 to { i1, { i1, i64, i1 } }* %155 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %154, align 4 %.fca.0.extract11.i.7 = extractvalue { i1, { i1, i64, i1 } } %155, 0 - br i1 %.fca.0.extract11.i.7, label %__hugr__.const_fun_284.290.exit.7, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.7, label %__hugr__.const_fun_287.338.exit.7, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.7: ; preds = %__hugr__.const_fun_284.290.exit.6 +__hugr__.const_fun_287.338.exit.7: ; preds = %__hugr__.const_fun_287.338.exit.6 %156 = extractvalue { i1, { i1, i64, i1 } } %155, 1 %157 = getelementptr inbounds i8, i8* %111, i64 168 %158 = bitcast i8* %157 to { i1, i64, i1 }* @@ -447,9 +447,9 @@ __hugr__.const_fun_284.290.exit.7: ; preds = %__hugr__.const_fun_ %160 = bitcast i8* %159 to { i1, { i1, i64, i1 } }* %161 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %160, align 4 %.fca.0.extract11.i.8 = extractvalue { i1, { i1, i64, i1 } } %161, 0 - br i1 %.fca.0.extract11.i.8, label %__hugr__.const_fun_284.290.exit.8, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.8, label %__hugr__.const_fun_287.338.exit.8, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.8: ; preds = %__hugr__.const_fun_284.290.exit.7 +__hugr__.const_fun_287.338.exit.8: ; preds = %__hugr__.const_fun_287.338.exit.7 %162 = extractvalue { i1, { i1, i64, i1 } } %161, 1 %163 = getelementptr inbounds i8, i8* %111, i64 192 %164 = bitcast i8* %163 to { i1, i64, i1 }* @@ -458,86 +458,86 @@ __hugr__.const_fun_284.290.exit.8: ; preds = %__hugr__.const_fun_ %166 = bitcast i8* %165 to { i1, { i1, i64, i1 } }* %167 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %166, align 4 %.fca.0.extract11.i.9 = extractvalue { i1, { i1, i64, i1 } } %167, 0 - br i1 %.fca.0.extract11.i.9, label %__hugr__.const_fun_284.290.exit.9, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.9, label %__hugr__.const_fun_287.338.exit.9, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.9: ; preds = %__hugr__.const_fun_284.290.exit.8 +__hugr__.const_fun_287.338.exit.9: ; preds = %__hugr__.const_fun_287.338.exit.8 %168 = extractvalue { i1, { i1, i64, i1 } } %167, 1 %169 = getelementptr inbounds i8, i8* %111, i64 216 %170 = bitcast i8* %169 to { i1, i64, i1 }* store { i1, i64, i1 } %168, { i1, i64, i1 }* %170, align 4 tail call void @heap_free(i8* nonnull %63) tail call void @heap_free(i8* nonnull %64) - br label %__barray_check_bounds.exit888 + br label %__barray_check_bounds.exit882 -cond_165_case_0: ; preds = %cond_exit_165 +cond_169_case_0: ; preds = %cond_exit_169 %171 = load i64, i64* %114, align 4 %172 = or i64 %171, -1024 store i64 %172, i64* %114, align 4 %173 = icmp eq i64 %172, -1 - br i1 %173, label %loop_out139, label %mask_block_err.i886 + br i1 %173, label %loop_out135, label %mask_block_err.i880 -mask_block_err.i886: ; preds = %cond_165_case_0 +mask_block_err.i880: ; preds = %cond_169_case_0 tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit888: ; preds = %__hugr__.const_fun_284.290.exit.9, %cond_exit_165 - %"167_0.0990" = phi i64 [ 0, %__hugr__.const_fun_284.290.exit.9 ], [ %174, %cond_exit_165 ] - %174 = add nuw nsw i64 %"167_0.0990", 1 - %175 = lshr i64 %"167_0.0990", 6 +__barray_check_bounds.exit882: ; preds = %__hugr__.const_fun_287.338.exit.9, %cond_exit_169 + %"172_0.0984" = phi i64 [ 0, %__hugr__.const_fun_287.338.exit.9 ], [ %174, %cond_exit_169 ] + %174 = add nuw nsw i64 %"172_0.0984", 1 + %175 = lshr i64 %"172_0.0984", 6 %176 = getelementptr inbounds i64, i64* %114, i64 %175 %177 = load i64, i64* %176, align 4 - %178 = shl nuw nsw i64 1, %"167_0.0990" + %178 = shl nuw nsw i64 1, %"172_0.0984" %179 = and i64 %177, %178 %.not = icmp eq i64 %179, 0 - br i1 %.not, label %__barray_mask_borrow.exit893, label %cond_exit_165 + br i1 %.not, label %__barray_mask_borrow.exit887, label %cond_exit_169 -__barray_mask_borrow.exit893: ; preds = %__barray_check_bounds.exit888 +__barray_mask_borrow.exit887: ; preds = %__barray_check_bounds.exit882 %180 = xor i64 %177, %178 store i64 %180, i64* %176, align 4 - %181 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %112, i64 %"167_0.0990" + %181 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %112, i64 %"172_0.0984" %182 = load { i1, i64, i1 }, { i1, i64, i1 }* %181, align 4 - %.fca.0.extract511 = extractvalue { i1, i64, i1 } %182, 0 - br i1 %.fca.0.extract511, label %cond_501_case_1, label %cond_exit_165 + %.fca.0.extract505 = extractvalue { i1, i64, i1 } %182, 0 + br i1 %.fca.0.extract505, label %cond_496_case_1, label %cond_exit_169 -cond_exit_165: ; preds = %cond_501_case_1, %__barray_mask_borrow.exit893, %__barray_check_bounds.exit888 - %183 = icmp ult i64 %"167_0.0990", 9 - br i1 %183, label %__barray_check_bounds.exit888, label %cond_165_case_0 +cond_exit_169: ; preds = %cond_496_case_1, %__barray_mask_borrow.exit887, %__barray_check_bounds.exit882 + %183 = icmp ult i64 %"172_0.0984", 9 + br i1 %183, label %__barray_check_bounds.exit882, label %cond_169_case_0 -loop_out139: ; preds = %cond_165_case_0 +loop_out135: ; preds = %cond_169_case_0 tail call void @heap_free(i8* %111) tail call void @heap_free(i8* nonnull %113) %184 = load i64, i64* %87, align 4 %185 = and i64 %184, 1023 store i64 %185, i64* %87, align 4 %186 = icmp eq i64 %185, 0 - br i1 %186, label %__barray_check_none_borrowed.exit898, label %mask_block_err.i897 + br i1 %186, label %__barray_check_none_borrowed.exit892, label %mask_block_err.i891 -__barray_check_none_borrowed.exit898: ; preds = %loop_out139 +__barray_check_none_borrowed.exit892: ; preds = %loop_out135 %187 = tail call i8* @heap_alloc(i64 10) %188 = tail call i8* @heap_alloc(i64 8) %189 = bitcast i8* %188 to i64* store i64 0, i64* %189, align 1 %190 = load { i1, i64, i1 }, { i1, i64, i1 }* %85, align 4 - %.fca.0.extract.i899 = extractvalue { i1, i64, i1 } %190, 0 - %.fca.1.extract.i900 = extractvalue { i1, i64, i1 } %190, 1 - br i1 %.fca.0.extract.i899, label %cond_300_case_1.i, label %cond_300_case_0.i + %.fca.0.extract.i893 = extractvalue { i1, i64, i1 } %190, 0 + %.fca.1.extract.i894 = extractvalue { i1, i64, i1 } %190, 1 + br i1 %.fca.0.extract.i893, label %cond_300_case_1.i, label %cond_300_case_0.i -mask_block_err.i897: ; preds = %loop_out139 +mask_block_err.i891: ; preds = %loop_out135 tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -cond_501_case_1: ; preds = %__barray_mask_borrow.exit893 - %.fca.1.extract512 = extractvalue { i1, i64, i1 } %182, 1 - tail call void @___dec_future_refcount(i64 %.fca.1.extract512) - br label %cond_exit_165 +cond_496_case_1: ; preds = %__barray_mask_borrow.exit887 + %.fca.1.extract506 = extractvalue { i1, i64, i1 } %182, 1 + tail call void @___dec_future_refcount(i64 %.fca.1.extract506) + br label %cond_exit_169 -cond_300_case_0.i: ; preds = %__barray_check_none_borrowed.exit898 +cond_300_case_0.i: ; preds = %__barray_check_none_borrowed.exit892 %.fca.2.extract.i = extractvalue { i1, i64, i1 } %190, 2 br label %__hugr__.array.__read_bool.3.271.exit -cond_300_case_1.i: ; preds = %__barray_check_none_borrowed.exit898 - %read_bool.i = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900) +cond_300_case_1.i: ; preds = %__barray_check_none_borrowed.exit892 + %read_bool.i = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894) br label %__hugr__.array.__read_bool.3.271.exit __hugr__.array.__read_bool.3.271.exit: ; preds = %cond_300_case_0.i, %cond_300_case_1.i @@ -547,17 +547,17 @@ __hugr__.array.__read_bool.3.271.exit: ; preds = %cond_300_case_0.i, %192 = getelementptr inbounds i8, i8* %84, i64 24 %193 = bitcast i8* %192 to { i1, i64, i1 }* %194 = load { i1, i64, i1 }, { i1, i64, i1 }* %193, align 4 - %.fca.0.extract.i899.1 = extractvalue { i1, i64, i1 } %194, 0 - %.fca.1.extract.i900.1 = extractvalue { i1, i64, i1 } %194, 1 - br i1 %.fca.0.extract.i899.1, label %cond_300_case_1.i.1, label %cond_300_case_0.i.1 + %.fca.0.extract.i893.1 = extractvalue { i1, i64, i1 } %194, 0 + %.fca.1.extract.i894.1 = extractvalue { i1, i64, i1 } %194, 1 + br i1 %.fca.0.extract.i893.1, label %cond_300_case_1.i.1, label %cond_300_case_0.i.1 cond_300_case_0.i.1: ; preds = %__hugr__.array.__read_bool.3.271.exit %.fca.2.extract.i.1 = extractvalue { i1, i64, i1 } %194, 2 br label %__hugr__.array.__read_bool.3.271.exit.1 cond_300_case_1.i.1: ; preds = %__hugr__.array.__read_bool.3.271.exit - %read_bool.i.1 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.1) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.1) + %read_bool.i.1 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.1) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.1) br label %__hugr__.array.__read_bool.3.271.exit.1 __hugr__.array.__read_bool.3.271.exit.1: ; preds = %cond_300_case_1.i.1, %cond_300_case_0.i.1 @@ -568,17 +568,17 @@ __hugr__.array.__read_bool.3.271.exit.1: ; preds = %cond_300_case_1.i.1 %197 = getelementptr inbounds i8, i8* %84, i64 48 %198 = bitcast i8* %197 to { i1, i64, i1 }* %199 = load { i1, i64, i1 }, { i1, i64, i1 }* %198, align 4 - %.fca.0.extract.i899.2 = extractvalue { i1, i64, i1 } %199, 0 - %.fca.1.extract.i900.2 = extractvalue { i1, i64, i1 } %199, 1 - br i1 %.fca.0.extract.i899.2, label %cond_300_case_1.i.2, label %cond_300_case_0.i.2 + %.fca.0.extract.i893.2 = extractvalue { i1, i64, i1 } %199, 0 + %.fca.1.extract.i894.2 = extractvalue { i1, i64, i1 } %199, 1 + br i1 %.fca.0.extract.i893.2, label %cond_300_case_1.i.2, label %cond_300_case_0.i.2 cond_300_case_0.i.2: ; preds = %__hugr__.array.__read_bool.3.271.exit.1 %.fca.2.extract.i.2 = extractvalue { i1, i64, i1 } %199, 2 br label %__hugr__.array.__read_bool.3.271.exit.2 cond_300_case_1.i.2: ; preds = %__hugr__.array.__read_bool.3.271.exit.1 - %read_bool.i.2 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.2) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.2) + %read_bool.i.2 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.2) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.2) br label %__hugr__.array.__read_bool.3.271.exit.2 __hugr__.array.__read_bool.3.271.exit.2: ; preds = %cond_300_case_1.i.2, %cond_300_case_0.i.2 @@ -589,17 +589,17 @@ __hugr__.array.__read_bool.3.271.exit.2: ; preds = %cond_300_case_1.i.2 %202 = getelementptr inbounds i8, i8* %84, i64 72 %203 = bitcast i8* %202 to { i1, i64, i1 }* %204 = load { i1, i64, i1 }, { i1, i64, i1 }* %203, align 4 - %.fca.0.extract.i899.3 = extractvalue { i1, i64, i1 } %204, 0 - %.fca.1.extract.i900.3 = extractvalue { i1, i64, i1 } %204, 1 - br i1 %.fca.0.extract.i899.3, label %cond_300_case_1.i.3, label %cond_300_case_0.i.3 + %.fca.0.extract.i893.3 = extractvalue { i1, i64, i1 } %204, 0 + %.fca.1.extract.i894.3 = extractvalue { i1, i64, i1 } %204, 1 + br i1 %.fca.0.extract.i893.3, label %cond_300_case_1.i.3, label %cond_300_case_0.i.3 cond_300_case_0.i.3: ; preds = %__hugr__.array.__read_bool.3.271.exit.2 %.fca.2.extract.i.3 = extractvalue { i1, i64, i1 } %204, 2 br label %__hugr__.array.__read_bool.3.271.exit.3 cond_300_case_1.i.3: ; preds = %__hugr__.array.__read_bool.3.271.exit.2 - %read_bool.i.3 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.3) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.3) + %read_bool.i.3 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.3) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.3) br label %__hugr__.array.__read_bool.3.271.exit.3 __hugr__.array.__read_bool.3.271.exit.3: ; preds = %cond_300_case_1.i.3, %cond_300_case_0.i.3 @@ -610,17 +610,17 @@ __hugr__.array.__read_bool.3.271.exit.3: ; preds = %cond_300_case_1.i.3 %207 = getelementptr inbounds i8, i8* %84, i64 96 %208 = bitcast i8* %207 to { i1, i64, i1 }* %209 = load { i1, i64, i1 }, { i1, i64, i1 }* %208, align 4 - %.fca.0.extract.i899.4 = extractvalue { i1, i64, i1 } %209, 0 - %.fca.1.extract.i900.4 = extractvalue { i1, i64, i1 } %209, 1 - br i1 %.fca.0.extract.i899.4, label %cond_300_case_1.i.4, label %cond_300_case_0.i.4 + %.fca.0.extract.i893.4 = extractvalue { i1, i64, i1 } %209, 0 + %.fca.1.extract.i894.4 = extractvalue { i1, i64, i1 } %209, 1 + br i1 %.fca.0.extract.i893.4, label %cond_300_case_1.i.4, label %cond_300_case_0.i.4 cond_300_case_0.i.4: ; preds = %__hugr__.array.__read_bool.3.271.exit.3 %.fca.2.extract.i.4 = extractvalue { i1, i64, i1 } %209, 2 br label %__hugr__.array.__read_bool.3.271.exit.4 cond_300_case_1.i.4: ; preds = %__hugr__.array.__read_bool.3.271.exit.3 - %read_bool.i.4 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.4) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.4) + %read_bool.i.4 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.4) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.4) br label %__hugr__.array.__read_bool.3.271.exit.4 __hugr__.array.__read_bool.3.271.exit.4: ; preds = %cond_300_case_1.i.4, %cond_300_case_0.i.4 @@ -631,17 +631,17 @@ __hugr__.array.__read_bool.3.271.exit.4: ; preds = %cond_300_case_1.i.4 %212 = getelementptr inbounds i8, i8* %84, i64 120 %213 = bitcast i8* %212 to { i1, i64, i1 }* %214 = load { i1, i64, i1 }, { i1, i64, i1 }* %213, align 4 - %.fca.0.extract.i899.5 = extractvalue { i1, i64, i1 } %214, 0 - %.fca.1.extract.i900.5 = extractvalue { i1, i64, i1 } %214, 1 - br i1 %.fca.0.extract.i899.5, label %cond_300_case_1.i.5, label %cond_300_case_0.i.5 + %.fca.0.extract.i893.5 = extractvalue { i1, i64, i1 } %214, 0 + %.fca.1.extract.i894.5 = extractvalue { i1, i64, i1 } %214, 1 + br i1 %.fca.0.extract.i893.5, label %cond_300_case_1.i.5, label %cond_300_case_0.i.5 cond_300_case_0.i.5: ; preds = %__hugr__.array.__read_bool.3.271.exit.4 %.fca.2.extract.i.5 = extractvalue { i1, i64, i1 } %214, 2 br label %__hugr__.array.__read_bool.3.271.exit.5 cond_300_case_1.i.5: ; preds = %__hugr__.array.__read_bool.3.271.exit.4 - %read_bool.i.5 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.5) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.5) + %read_bool.i.5 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.5) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.5) br label %__hugr__.array.__read_bool.3.271.exit.5 __hugr__.array.__read_bool.3.271.exit.5: ; preds = %cond_300_case_1.i.5, %cond_300_case_0.i.5 @@ -652,17 +652,17 @@ __hugr__.array.__read_bool.3.271.exit.5: ; preds = %cond_300_case_1.i.5 %217 = getelementptr inbounds i8, i8* %84, i64 144 %218 = bitcast i8* %217 to { i1, i64, i1 }* %219 = load { i1, i64, i1 }, { i1, i64, i1 }* %218, align 4 - %.fca.0.extract.i899.6 = extractvalue { i1, i64, i1 } %219, 0 - %.fca.1.extract.i900.6 = extractvalue { i1, i64, i1 } %219, 1 - br i1 %.fca.0.extract.i899.6, label %cond_300_case_1.i.6, label %cond_300_case_0.i.6 + %.fca.0.extract.i893.6 = extractvalue { i1, i64, i1 } %219, 0 + %.fca.1.extract.i894.6 = extractvalue { i1, i64, i1 } %219, 1 + br i1 %.fca.0.extract.i893.6, label %cond_300_case_1.i.6, label %cond_300_case_0.i.6 cond_300_case_0.i.6: ; preds = %__hugr__.array.__read_bool.3.271.exit.5 %.fca.2.extract.i.6 = extractvalue { i1, i64, i1 } %219, 2 br label %__hugr__.array.__read_bool.3.271.exit.6 cond_300_case_1.i.6: ; preds = %__hugr__.array.__read_bool.3.271.exit.5 - %read_bool.i.6 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.6) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.6) + %read_bool.i.6 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.6) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.6) br label %__hugr__.array.__read_bool.3.271.exit.6 __hugr__.array.__read_bool.3.271.exit.6: ; preds = %cond_300_case_1.i.6, %cond_300_case_0.i.6 @@ -673,17 +673,17 @@ __hugr__.array.__read_bool.3.271.exit.6: ; preds = %cond_300_case_1.i.6 %222 = getelementptr inbounds i8, i8* %84, i64 168 %223 = bitcast i8* %222 to { i1, i64, i1 }* %224 = load { i1, i64, i1 }, { i1, i64, i1 }* %223, align 4 - %.fca.0.extract.i899.7 = extractvalue { i1, i64, i1 } %224, 0 - %.fca.1.extract.i900.7 = extractvalue { i1, i64, i1 } %224, 1 - br i1 %.fca.0.extract.i899.7, label %cond_300_case_1.i.7, label %cond_300_case_0.i.7 + %.fca.0.extract.i893.7 = extractvalue { i1, i64, i1 } %224, 0 + %.fca.1.extract.i894.7 = extractvalue { i1, i64, i1 } %224, 1 + br i1 %.fca.0.extract.i893.7, label %cond_300_case_1.i.7, label %cond_300_case_0.i.7 cond_300_case_0.i.7: ; preds = %__hugr__.array.__read_bool.3.271.exit.6 %.fca.2.extract.i.7 = extractvalue { i1, i64, i1 } %224, 2 br label %__hugr__.array.__read_bool.3.271.exit.7 cond_300_case_1.i.7: ; preds = %__hugr__.array.__read_bool.3.271.exit.6 - %read_bool.i.7 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.7) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.7) + %read_bool.i.7 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.7) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.7) br label %__hugr__.array.__read_bool.3.271.exit.7 __hugr__.array.__read_bool.3.271.exit.7: ; preds = %cond_300_case_1.i.7, %cond_300_case_0.i.7 @@ -694,17 +694,17 @@ __hugr__.array.__read_bool.3.271.exit.7: ; preds = %cond_300_case_1.i.7 %227 = getelementptr inbounds i8, i8* %84, i64 192 %228 = bitcast i8* %227 to { i1, i64, i1 }* %229 = load { i1, i64, i1 }, { i1, i64, i1 }* %228, align 4 - %.fca.0.extract.i899.8 = extractvalue { i1, i64, i1 } %229, 0 - %.fca.1.extract.i900.8 = extractvalue { i1, i64, i1 } %229, 1 - br i1 %.fca.0.extract.i899.8, label %cond_300_case_1.i.8, label %cond_300_case_0.i.8 + %.fca.0.extract.i893.8 = extractvalue { i1, i64, i1 } %229, 0 + %.fca.1.extract.i894.8 = extractvalue { i1, i64, i1 } %229, 1 + br i1 %.fca.0.extract.i893.8, label %cond_300_case_1.i.8, label %cond_300_case_0.i.8 cond_300_case_0.i.8: ; preds = %__hugr__.array.__read_bool.3.271.exit.7 %.fca.2.extract.i.8 = extractvalue { i1, i64, i1 } %229, 2 br label %__hugr__.array.__read_bool.3.271.exit.8 cond_300_case_1.i.8: ; preds = %__hugr__.array.__read_bool.3.271.exit.7 - %read_bool.i.8 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.8) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.8) + %read_bool.i.8 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.8) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.8) br label %__hugr__.array.__read_bool.3.271.exit.8 __hugr__.array.__read_bool.3.271.exit.8: ; preds = %cond_300_case_1.i.8, %cond_300_case_0.i.8 @@ -715,17 +715,17 @@ __hugr__.array.__read_bool.3.271.exit.8: ; preds = %cond_300_case_1.i.8 %232 = getelementptr inbounds i8, i8* %84, i64 216 %233 = bitcast i8* %232 to { i1, i64, i1 }* %234 = load { i1, i64, i1 }, { i1, i64, i1 }* %233, align 4 - %.fca.0.extract.i899.9 = extractvalue { i1, i64, i1 } %234, 0 - %.fca.1.extract.i900.9 = extractvalue { i1, i64, i1 } %234, 1 - br i1 %.fca.0.extract.i899.9, label %cond_300_case_1.i.9, label %cond_300_case_0.i.9 + %.fca.0.extract.i893.9 = extractvalue { i1, i64, i1 } %234, 0 + %.fca.1.extract.i894.9 = extractvalue { i1, i64, i1 } %234, 1 + br i1 %.fca.0.extract.i893.9, label %cond_300_case_1.i.9, label %cond_300_case_0.i.9 cond_300_case_0.i.9: ; preds = %__hugr__.array.__read_bool.3.271.exit.8 %.fca.2.extract.i.9 = extractvalue { i1, i64, i1 } %234, 2 br label %__hugr__.array.__read_bool.3.271.exit.9 cond_300_case_1.i.9: ; preds = %__hugr__.array.__read_bool.3.271.exit.8 - %read_bool.i.9 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.9) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.9) + %read_bool.i.9 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.9) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.9) br label %__hugr__.array.__read_bool.3.271.exit.9 __hugr__.array.__read_bool.3.271.exit.9: ; preds = %cond_300_case_1.i.9, %cond_300_case_0.i.9 @@ -739,9 +739,9 @@ __hugr__.array.__read_bool.3.271.exit.9: ; preds = %cond_300_case_1.i.9 %238 = and i64 %237, 1023 store i64 %238, i64* %189, align 4 %239 = icmp eq i64 %238, 0 - br i1 %239, label %__barray_check_none_borrowed.exit905, label %mask_block_err.i904 + br i1 %239, label %__barray_check_none_borrowed.exit899, label %mask_block_err.i898 -__barray_check_none_borrowed.exit905: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 +__barray_check_none_borrowed.exit899: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 %out_arr_alloca = alloca <{ i32, i32, i1*, i1* }>, align 8 %x_ptr = getelementptr inbounds <{ i32, i32, i1*, i1* }>, <{ i32, i32, i1*, i1* }>* %out_arr_alloca, i64 0, i32 0 %y_ptr = getelementptr inbounds <{ i32, i32, i1*, i1* }>, <{ i32, i32, i1*, i1* }>* %out_arr_alloca, i64 0, i32 1 @@ -757,37 +757,37 @@ __barray_check_none_borrowed.exit905: ; preds = %__hugr__.array.__re store i8* %187, i8** %242, align 8 store i1* %.sub, i1** %mask_ptr, align 8 call void @print_bool_arr(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @res_cs.46C3C4B5.0, i64 0, i64 0), i64 15, <{ i32, i32, i1*, i1* }>* nonnull %out_arr_alloca) - br label %__barray_check_bounds.exit913 + br label %__barray_check_bounds.exit907 -mask_block_err.i904: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 +mask_block_err.i898: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit913: ; preds = %cond_exit_95, %__barray_check_none_borrowed.exit905 - %"90_0.sroa.0.0972" = phi i64 [ 0, %__barray_check_none_borrowed.exit905 ], [ %243, %cond_exit_95 ] - %243 = add nuw nsw i64 %"90_0.sroa.0.0972", 1 - %244 = lshr i64 %"90_0.sroa.0.0972", 6 +__barray_check_bounds.exit907: ; preds = %cond_exit_95, %__barray_check_none_borrowed.exit899 + %"90_0.sroa.0.0966" = phi i64 [ 0, %__barray_check_none_borrowed.exit899 ], [ %243, %cond_exit_95 ] + %243 = add nuw nsw i64 %"90_0.sroa.0.0966", 1 + %244 = lshr i64 %"90_0.sroa.0.0966", 6 %245 = getelementptr inbounds i64, i64* %7, i64 %244 %246 = load i64, i64* %245, align 4 - %247 = and i64 %"90_0.sroa.0.0972", 63 + %247 = and i64 %"90_0.sroa.0.0966", 63 %248 = shl nuw i64 1, %247 %249 = and i64 %246, %248 - %.not.i914 = icmp eq i64 %249, 0 - br i1 %.not.i914, label %panic.i915, label %cond_exit_95 + %.not.i908 = icmp eq i64 %249, 0 + br i1 %.not.i908, label %panic.i909, label %cond_exit_95 -panic.i915: ; preds = %__barray_check_bounds.exit913 +panic.i909: ; preds = %__barray_check_bounds.exit907 call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -cond_exit_95: ; preds = %__barray_check_bounds.exit913 +cond_exit_95: ; preds = %__barray_check_bounds.exit907 %250 = xor i64 %246, %248 store i64 %250, i64* %245, align 4 - %251 = getelementptr inbounds i64, i64* %5, i64 %"90_0.sroa.0.0972" - store i64 %"90_0.sroa.0.0972", i64* %251, align 4 - %exitcond984.not = icmp eq i64 %243, 100 - br i1 %exitcond984.not, label %loop_out212, label %__barray_check_bounds.exit913 + %251 = getelementptr inbounds i64, i64* %5, i64 %"90_0.sroa.0.0966" + store i64 %"90_0.sroa.0.0966", i64* %251, align 4 + %exitcond978.not = icmp eq i64 %243, 100 + br i1 %exitcond978.not, label %loop_out208, label %__barray_check_bounds.exit907 -loop_out212: ; preds = %cond_exit_95 +loop_out208: ; preds = %cond_exit_95 %252 = getelementptr inbounds i8, i8* %6, i64 8 %253 = bitcast i8* %252 to i64* %254 = load i64, i64* %253, align 4 @@ -797,9 +797,9 @@ loop_out212: ; preds = %cond_exit_95 %257 = icmp eq i64 %256, 0 %258 = icmp eq i64 %255, 0 %or.cond = select i1 %257, i1 %258, i1 false - br i1 %or.cond, label %__barray_check_none_borrowed.exit921, label %mask_block_err.i920 + br i1 %or.cond, label %__barray_check_none_borrowed.exit915, label %mask_block_err.i914 -__barray_check_none_borrowed.exit921: ; preds = %loop_out212 +__barray_check_none_borrowed.exit915: ; preds = %loop_out208 %259 = call i8* @heap_alloc(i64 800) %260 = bitcast i8* %259 to i64* %261 = call i8* @heap_alloc(i64 16) @@ -813,62 +813,62 @@ __barray_check_none_borrowed.exit921: ; preds = %loop_out212 %265 = load i64, i64* %7, align 4 %266 = icmp eq i64 %265, 0 %267 = icmp eq i64 %264, 0 - %or.cond987 = select i1 %266, i1 %267, i1 false - br i1 %or.cond987, label %__barray_check_none_borrowed.exit926, label %mask_block_err.i925 + %or.cond981 = select i1 %266, i1 %267, i1 false + br i1 %or.cond981, label %__barray_check_none_borrowed.exit920, label %mask_block_err.i919 -mask_block_err.i920: ; preds = %loop_out212 +mask_block_err.i914: ; preds = %loop_out208 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_none_borrowed.exit926: ; preds = %__barray_check_none_borrowed.exit921 - %out_arr_alloca287 = alloca <{ i32, i32, i64*, i1* }>, align 8 - %x_ptr288 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 0 - %y_ptr289 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 1 - %arr_ptr290 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 2 - %mask_ptr291 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 3 +__barray_check_none_borrowed.exit920: ; preds = %__barray_check_none_borrowed.exit915 + %out_arr_alloca282 = alloca <{ i32, i32, i64*, i1* }>, align 8 + %x_ptr283 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 0 + %y_ptr284 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 1 + %arr_ptr285 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 2 + %mask_ptr286 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 3 %268 = alloca [100 x i1], align 1 - %.sub635 = getelementptr inbounds [100 x i1], [100 x i1]* %268, i64 0, i64 0 + %.sub629 = getelementptr inbounds [100 x i1], [100 x i1]* %268, i64 0, i64 0 %269 = bitcast [100 x i1]* %268 to i8* call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(100) %269, i8 0, i64 100, i1 false) - store i32 100, i32* %x_ptr288, align 8 - store i32 1, i32* %y_ptr289, align 4 - %270 = bitcast i64** %arr_ptr290 to i8** + store i32 100, i32* %x_ptr283, align 8 + store i32 1, i32* %y_ptr284, align 4 + %270 = bitcast i64** %arr_ptr285 to i8** store i8* %4, i8** %270, align 8 - store i1* %.sub635, i1** %mask_ptr291, align 8 - call void @print_int_arr(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @res_is.F21393DB.0, i64 0, i64 0), i64 14, <{ i32, i32, i64*, i1* }>* nonnull %out_arr_alloca287) - br label %__barray_check_bounds.exit934 + store i1* %.sub629, i1** %mask_ptr286, align 8 + call void @print_int_arr(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @res_is.F21393DB.0, i64 0, i64 0), i64 14, <{ i32, i32, i64*, i1* }>* nonnull %out_arr_alloca282) + br label %__barray_check_bounds.exit928 -mask_block_err.i925: ; preds = %__barray_check_none_borrowed.exit921 +mask_block_err.i919: ; preds = %__barray_check_none_borrowed.exit915 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit934: ; preds = %cond_exit_130, %__barray_check_none_borrowed.exit926 - %"125_0.sroa.0.0974" = phi i64 [ 0, %__barray_check_none_borrowed.exit926 ], [ %271, %cond_exit_130 ] - %271 = add nuw nsw i64 %"125_0.sroa.0.0974", 1 - %272 = lshr i64 %"125_0.sroa.0.0974", 6 +__barray_check_bounds.exit928: ; preds = %cond_exit_130, %__barray_check_none_borrowed.exit920 + %"125_0.sroa.0.0968" = phi i64 [ 0, %__barray_check_none_borrowed.exit920 ], [ %271, %cond_exit_130 ] + %271 = add nuw nsw i64 %"125_0.sroa.0.0968", 1 + %272 = lshr i64 %"125_0.sroa.0.0968", 6 %273 = getelementptr inbounds i64, i64* %3, i64 %272 %274 = load i64, i64* %273, align 4 - %275 = and i64 %"125_0.sroa.0.0974", 63 + %275 = and i64 %"125_0.sroa.0.0968", 63 %276 = shl nuw i64 1, %275 %277 = and i64 %274, %276 - %.not.i935 = icmp eq i64 %277, 0 - br i1 %.not.i935, label %panic.i936, label %cond_exit_130 + %.not.i929 = icmp eq i64 %277, 0 + br i1 %.not.i929, label %panic.i930, label %cond_exit_130 -panic.i936: ; preds = %__barray_check_bounds.exit934 +panic.i930: ; preds = %__barray_check_bounds.exit928 call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -cond_exit_130: ; preds = %__barray_check_bounds.exit934 - %278 = sitofp i64 %"125_0.sroa.0.0974" to double +cond_exit_130: ; preds = %__barray_check_bounds.exit928 + %278 = sitofp i64 %"125_0.sroa.0.0968" to double %279 = fmul double %278, 6.250000e-02 %280 = xor i64 %274, %276 store i64 %280, i64* %273, align 4 - %281 = getelementptr inbounds double, double* %1, i64 %"125_0.sroa.0.0974" + %281 = getelementptr inbounds double, double* %1, i64 %"125_0.sroa.0.0968" store double %279, double* %281, align 8 - %exitcond985.not = icmp eq i64 %271, 100 - br i1 %exitcond985.not, label %loop_out299, label %__barray_check_bounds.exit934 + %exitcond979.not = icmp eq i64 %271, 100 + br i1 %exitcond979.not, label %loop_out294, label %__barray_check_bounds.exit928 -loop_out299: ; preds = %cond_exit_130 +loop_out294: ; preds = %cond_exit_130 %282 = getelementptr inbounds i8, i8* %2, i64 8 %283 = bitcast i8* %282 to i64* %284 = load i64, i64* %283, align 4 @@ -877,10 +877,10 @@ loop_out299: ; preds = %cond_exit_130 %286 = load i64, i64* %3, align 4 %287 = icmp eq i64 %286, 0 %288 = icmp eq i64 %285, 0 - %or.cond988 = select i1 %287, i1 %288, i1 false - br i1 %or.cond988, label %__barray_check_none_borrowed.exit942, label %mask_block_err.i941 + %or.cond982 = select i1 %287, i1 %288, i1 false + br i1 %or.cond982, label %__barray_check_none_borrowed.exit936, label %mask_block_err.i935 -__barray_check_none_borrowed.exit942: ; preds = %loop_out299 +__barray_check_none_borrowed.exit936: ; preds = %loop_out294 %289 = call i8* @heap_alloc(i64 800) %290 = bitcast i8* %289 to double* %291 = call i8* @heap_alloc(i64 16) @@ -894,32 +894,32 @@ __barray_check_none_borrowed.exit942: ; preds = %loop_out299 %295 = load i64, i64* %3, align 4 %296 = icmp eq i64 %295, 0 %297 = icmp eq i64 %294, 0 - %or.cond989 = select i1 %296, i1 %297, i1 false - br i1 %or.cond989, label %__barray_check_none_borrowed.exit947, label %mask_block_err.i946 + %or.cond983 = select i1 %296, i1 %297, i1 false + br i1 %or.cond983, label %__barray_check_none_borrowed.exit941, label %mask_block_err.i940 -mask_block_err.i941: ; preds = %loop_out299 +mask_block_err.i935: ; preds = %loop_out294 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_none_borrowed.exit947: ; preds = %__barray_check_none_borrowed.exit942 - %out_arr_alloca377 = alloca <{ i32, i32, double*, i1* }>, align 8 - %x_ptr378 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 0 - %y_ptr379 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 1 - %arr_ptr380 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 2 - %mask_ptr381 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 3 +__barray_check_none_borrowed.exit941: ; preds = %__barray_check_none_borrowed.exit936 + %out_arr_alloca371 = alloca <{ i32, i32, double*, i1* }>, align 8 + %x_ptr372 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 0 + %y_ptr373 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 1 + %arr_ptr374 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 2 + %mask_ptr375 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 3 %298 = alloca [100 x i1], align 1 - %.sub736 = getelementptr inbounds [100 x i1], [100 x i1]* %298, i64 0, i64 0 + %.sub730 = getelementptr inbounds [100 x i1], [100 x i1]* %298, i64 0, i64 0 %299 = bitcast [100 x i1]* %298 to i8* call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(100) %299, i8 0, i64 100, i1 false) - store i32 100, i32* %x_ptr378, align 8 - store i32 1, i32* %y_ptr379, align 4 - %300 = bitcast double** %arr_ptr380 to i8** + store i32 100, i32* %x_ptr372, align 8 + store i32 1, i32* %y_ptr373, align 4 + %300 = bitcast double** %arr_ptr374 to i8** store i8* %0, i8** %300, align 8 - store i1* %.sub736, i1** %mask_ptr381, align 8 - call void @print_float_arr(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @res_fs.CBD4AF54.0, i64 0, i64 0), i64 16, <{ i32, i32, double*, i1* }>* nonnull %out_arr_alloca377) + store i1* %.sub730, i1** %mask_ptr375, align 8 + call void @print_float_arr(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @res_fs.CBD4AF54.0, i64 0, i64 0), i64 16, <{ i32, i32, double*, i1* }>* nonnull %out_arr_alloca371) ret void -mask_block_err.i946: ; preds = %__barray_check_none_borrowed.exit942 +mask_block_err.i940: ; preds = %__barray_check_none_borrowed.exit936 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable } diff --git a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-apple-darwin-measure_qb_array/measure_qb_array_x86_64-apple-darwin b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-apple-darwin-measure_qb_array/measure_qb_array_x86_64-apple-darwin index f3c8c0092..aa1e328f5 100644 --- a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-apple-darwin-measure_qb_array/measure_qb_array_x86_64-apple-darwin +++ b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-apple-darwin-measure_qb_array/measure_qb_array_x86_64-apple-darwin @@ -38,8 +38,8 @@ entry: br label %cond_20_case_1.i cond_20_case_1.i: ; preds = %cond_exit_20.i, %entry - %"15_0.sroa.0.0295.i" = phi i64 [ 0, %entry ], [ %5, %cond_exit_20.i ] - %5 = add nuw nsw i64 %"15_0.sroa.0.0295.i", 1 + %"15_0.sroa.0.0294.i" = phi i64 [ 0, %entry ], [ %5, %cond_exit_20.i ] + %5 = add nuw nsw i64 %"15_0.sroa.0.0294.i", 1 %qalloc.i.i = tail call i64 @___qalloc() %not_max.not.i.i = icmp eq i64 %qalloc.i.i, -1 br i1 %not_max.not.i.i, label %id_bb.i.i, label %reset_bb.i.i @@ -59,10 +59,10 @@ cond_217_case_0.i.i: ; preds = %id_bb.i.i unreachable __barray_check_bounds.exit.i: ; preds = %id_bb.i.i - %8 = lshr i64 %"15_0.sroa.0.0295.i", 6 + %8 = lshr i64 %"15_0.sroa.0.0294.i", 6 %9 = getelementptr inbounds i64, i64* %4, i64 %8 %10 = load i64, i64* %9, align 4 - %11 = shl nuw nsw i64 1, %"15_0.sroa.0.0295.i" + %11 = shl nuw nsw i64 1, %"15_0.sroa.0.0294.i" %12 = and i64 %10, %11 %.not.i.i = icmp eq i64 %12, 0 br i1 %.not.i.i, label %panic.i.i, label %cond_exit_20.i @@ -75,7 +75,7 @@ cond_exit_20.i: ; preds = %__barray_check_boun %.fca.1.extract.i.i = extractvalue { i1, i64 } %7, 1 %13 = xor i64 %10, %11 store i64 %13, i64* %9, align 4 - %14 = getelementptr inbounds i64, i64* %2, i64 %"15_0.sroa.0.0295.i" + %14 = getelementptr inbounds i64, i64* %2, i64 %"15_0.sroa.0.0294.i" store i64 %.fca.1.extract.i.i, i64* %14, align 4 %exitcond.not.i = icmp eq i64 %5, 10 br i1 %exitcond.not.i, label %loop_out.i, label %cond_20_case_1.i @@ -83,10 +83,10 @@ cond_exit_20.i: ; preds = %__barray_check_boun loop_out.i: ; preds = %cond_exit_20.i %15 = load i64, i64* %4, align 4 %16 = and i64 %15, 1 - %.not.i259.i = icmp eq i64 %16, 0 - br i1 %.not.i259.i, label %__barray_mask_borrow.exit.i, label %panic.i260.i + %.not.i258.i = icmp eq i64 %16, 0 + br i1 %.not.i258.i, label %__barray_mask_borrow.exit.i, label %panic.i259.i -panic.i260.i: ; preds = %loop_out.i +panic.i259.i: ; preds = %loop_out.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable @@ -97,27 +97,27 @@ __barray_mask_borrow.exit.i: ; preds = %loop_out.i tail call void @___rxy(i64 %18, double 0x400921FB54442D18, double 0.000000e+00) %19 = load i64, i64* %4, align 4 %20 = and i64 %19, 1 - %.not.i261.i = icmp eq i64 %20, 0 - br i1 %.not.i261.i, label %panic.i262.i, label %__barray_mask_return.exit263.i + %.not.i260.i = icmp eq i64 %20, 0 + br i1 %.not.i260.i, label %panic.i261.i, label %__barray_mask_return.exit262.i -panic.i262.i: ; preds = %__barray_mask_borrow.exit.i +panic.i261.i: ; preds = %__barray_mask_borrow.exit.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit263.i: ; preds = %__barray_mask_borrow.exit.i +__barray_mask_return.exit262.i: ; preds = %__barray_mask_borrow.exit.i %21 = xor i64 %19, 1 store i64 %21, i64* %4, align 4 store i64 %18, i64* %2, align 4 %22 = load i64, i64* %4, align 4 %23 = and i64 %22, 4 - %.not.i264.i = icmp eq i64 %23, 0 - br i1 %.not.i264.i, label %__barray_mask_borrow.exit266.i, label %panic.i265.i + %.not.i263.i = icmp eq i64 %23, 0 + br i1 %.not.i263.i, label %__barray_mask_borrow.exit265.i, label %panic.i264.i -panic.i265.i: ; preds = %__barray_mask_return.exit263.i +panic.i264.i: ; preds = %__barray_mask_return.exit262.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit266.i: ; preds = %__barray_mask_return.exit263.i +__barray_mask_borrow.exit265.i: ; preds = %__barray_mask_return.exit262.i %24 = xor i64 %22, 4 store i64 %24, i64* %4, align 4 %25 = getelementptr inbounds i8, i8* %1, i64 16 @@ -126,27 +126,27 @@ __barray_mask_borrow.exit266.i: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %27, double 0x400921FB54442D18, double 0.000000e+00) %28 = load i64, i64* %4, align 4 %29 = and i64 %28, 4 - %.not.i267.i = icmp eq i64 %29, 0 - br i1 %.not.i267.i, label %panic.i268.i, label %__barray_mask_return.exit269.i + %.not.i266.i = icmp eq i64 %29, 0 + br i1 %.not.i266.i, label %panic.i267.i, label %__barray_mask_return.exit268.i -panic.i268.i: ; preds = %__barray_mask_borrow.exit266.i +panic.i267.i: ; preds = %__barray_mask_borrow.exit265.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit269.i: ; preds = %__barray_mask_borrow.exit266.i +__barray_mask_return.exit268.i: ; preds = %__barray_mask_borrow.exit265.i %30 = xor i64 %28, 4 store i64 %30, i64* %4, align 4 store i64 %27, i64* %26, align 4 %31 = load i64, i64* %4, align 4 %32 = and i64 %31, 8 - %.not.i270.i = icmp eq i64 %32, 0 - br i1 %.not.i270.i, label %__barray_mask_borrow.exit272.i, label %panic.i271.i + %.not.i269.i = icmp eq i64 %32, 0 + br i1 %.not.i269.i, label %__barray_mask_borrow.exit271.i, label %panic.i270.i -panic.i271.i: ; preds = %__barray_mask_return.exit269.i +panic.i270.i: ; preds = %__barray_mask_return.exit268.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit272.i: ; preds = %__barray_mask_return.exit269.i +__barray_mask_borrow.exit271.i: ; preds = %__barray_mask_return.exit268.i %33 = xor i64 %31, 8 store i64 %33, i64* %4, align 4 %34 = getelementptr inbounds i8, i8* %1, i64 24 @@ -155,27 +155,27 @@ __barray_mask_borrow.exit272.i: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %36, double 0x400921FB54442D18, double 0.000000e+00) %37 = load i64, i64* %4, align 4 %38 = and i64 %37, 8 - %.not.i273.i = icmp eq i64 %38, 0 - br i1 %.not.i273.i, label %panic.i274.i, label %__barray_mask_return.exit275.i + %.not.i272.i = icmp eq i64 %38, 0 + br i1 %.not.i272.i, label %panic.i273.i, label %__barray_mask_return.exit274.i -panic.i274.i: ; preds = %__barray_mask_borrow.exit272.i +panic.i273.i: ; preds = %__barray_mask_borrow.exit271.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit275.i: ; preds = %__barray_mask_borrow.exit272.i +__barray_mask_return.exit274.i: ; preds = %__barray_mask_borrow.exit271.i %39 = xor i64 %37, 8 store i64 %39, i64* %4, align 4 store i64 %36, i64* %35, align 4 %40 = load i64, i64* %4, align 4 %41 = and i64 %40, 512 - %.not.i276.i = icmp eq i64 %41, 0 - br i1 %.not.i276.i, label %__barray_mask_borrow.exit278.i, label %panic.i277.i + %.not.i275.i = icmp eq i64 %41, 0 + br i1 %.not.i275.i, label %__barray_mask_borrow.exit277.i, label %panic.i276.i -panic.i277.i: ; preds = %__barray_mask_return.exit275.i +panic.i276.i: ; preds = %__barray_mask_return.exit274.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit278.i: ; preds = %__barray_mask_return.exit275.i +__barray_mask_borrow.exit277.i: ; preds = %__barray_mask_return.exit274.i %42 = xor i64 %40, 512 store i64 %42, i64* %4, align 4 %43 = getelementptr inbounds i8, i8* %1, i64 72 @@ -184,14 +184,14 @@ __barray_mask_borrow.exit278.i: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %45, double 0x400921FB54442D18, double 0.000000e+00) %46 = load i64, i64* %4, align 4 %47 = and i64 %46, 512 - %.not.i279.i = icmp eq i64 %47, 0 - br i1 %.not.i279.i, label %panic.i280.i, label %__barray_mask_return.exit281.i + %.not.i278.i = icmp eq i64 %47, 0 + br i1 %.not.i278.i, label %panic.i279.i, label %__barray_mask_return.exit280.i -panic.i280.i: ; preds = %__barray_mask_borrow.exit278.i +panic.i279.i: ; preds = %__barray_mask_borrow.exit277.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit281.i: ; preds = %__barray_mask_borrow.exit278.i +__barray_mask_return.exit280.i: ; preds = %__barray_mask_borrow.exit277.i %48 = xor i64 %46, 512 store i64 %48, i64* %4, align 4 store i64 %45, i64* %44, align 4 @@ -212,19 +212,19 @@ mask_block_ok.i.i.i.i: ; preds = %cond_exit_353.i.i "__hugr__.$measure_array$$n(10).277.exit.i": ; preds = %mask_block_ok.i.i.i.i tail call void @heap_free(i8* nonnull %1) tail call void @heap_free(i8* nonnull %3) - br label %__barray_check_bounds.exit284.i + br label %__barray_check_bounds.exit283.i mask_block_err.i.i.i.i: ; preds = %mask_block_ok.i.i.i.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -56: ; preds = %cond_exit_353.i.i, %__barray_mask_return.exit281.i - %"303_0.sroa.15.0.i297.i" = phi i64 [ 0, %__barray_mask_return.exit281.i ], [ %57, %cond_exit_353.i.i ] - %57 = add nuw nsw i64 %"303_0.sroa.15.0.i297.i", 1 - %58 = lshr i64 %"303_0.sroa.15.0.i297.i", 6 +56: ; preds = %cond_exit_353.i.i, %__barray_mask_return.exit280.i + %"303_0.sroa.15.0.i296.i" = phi i64 [ 0, %__barray_mask_return.exit280.i ], [ %57, %cond_exit_353.i.i ] + %57 = add nuw nsw i64 %"303_0.sroa.15.0.i296.i", 1 + %58 = lshr i64 %"303_0.sroa.15.0.i296.i", 6 %59 = getelementptr inbounds i64, i64* %4, i64 %58 %60 = load i64, i64* %59, align 4 - %61 = shl nuw nsw i64 1, %"303_0.sroa.15.0.i297.i" + %61 = shl nuw nsw i64 1, %"303_0.sroa.15.0.i296.i" %62 = and i64 %60, %61 %.not.i99.i.i.i = icmp eq i64 %62, 0 br i1 %.not.i99.i.i.i, label %__barray_check_bounds.exit.i.i, label %panic.i.i.i.i @@ -236,7 +236,7 @@ panic.i.i.i.i: ; preds = %56 __barray_check_bounds.exit.i.i: ; preds = %56 %63 = xor i64 %60, %61 store i64 %63, i64* %59, align 4 - %64 = getelementptr inbounds i64, i64* %2, i64 %"303_0.sroa.15.0.i297.i" + %64 = getelementptr inbounds i64, i64* %2, i64 %"303_0.sroa.15.0.i296.i" %65 = load i64, i64* %64, align 4 %lazy_measure.i.i = tail call i64 @___lazy_measure(i64 %65) tail call void @___qfree(i64 %65) @@ -254,51 +254,51 @@ cond_exit_353.i.i: ; preds = %__barray_check_boun %"367_054.fca.1.insert.i.i" = insertvalue { i1, i64, i1 } { i1 true, i64 poison, i1 poison }, i64 %lazy_measure.i.i, 1 %69 = xor i64 %67, %61 store i64 %69, i64* %66, align 4 - %70 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"303_0.sroa.15.0.i297.i" + %70 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"303_0.sroa.15.0.i296.i" store { i1, i64, i1 } %"367_054.fca.1.insert.i.i", { i1, i64, i1 }* %70, align 4 - %exitcond298.not.i = icmp eq i64 %57, 10 - br i1 %exitcond298.not.i, label %mask_block_ok.i.i.i.i, label %56 + %exitcond297.not.i = icmp eq i64 %57, 10 + br i1 %exitcond297.not.i, label %mask_block_ok.i.i.i.i, label %56 -cond_160_case_0.i: ; preds = %cond_exit_160.i +cond_187_case_0.i: ; preds = %cond_exit_187.i %71 = load i64, i64* %52, align 4 %72 = or i64 %71, -1024 store i64 %72, i64* %52, align 4 %73 = icmp eq i64 %72, -1 br i1 %73, label %__hugr__.main.1.exit, label %mask_block_err.i.i -mask_block_err.i.i: ; preds = %cond_160_case_0.i +mask_block_err.i.i: ; preds = %cond_187_case_0.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit284.i: ; preds = %"__hugr__.$measure_array$$n(10).277.exit.i", %cond_exit_160.i - %"162_0.0.i1" = phi i64 [ 0, %"__hugr__.$measure_array$$n(10).277.exit.i" ], [ %82, %cond_exit_160.i ] - %74 = lshr i64 %"162_0.0.i1", 6 +__barray_check_bounds.exit283.i: ; preds = %"__hugr__.$measure_array$$n(10).277.exit.i", %cond_exit_187.i + %"164_0.0.i1" = phi i64 [ 0, %"__hugr__.$measure_array$$n(10).277.exit.i" ], [ %82, %cond_exit_187.i ] + %74 = lshr i64 %"164_0.0.i1", 6 %75 = getelementptr inbounds i64, i64* %52, i64 %74 %76 = load i64, i64* %75, align 4 - %77 = shl nuw nsw i64 1, %"162_0.0.i1" + %77 = shl nuw nsw i64 1, %"164_0.0.i1" %78 = and i64 %76, %77 %.not.i = icmp eq i64 %78, 0 - br i1 %.not.i, label %__barray_mask_borrow.exit289.i, label %cond_exit_160.i + br i1 %.not.i, label %__barray_mask_borrow.exit288.i, label %cond_exit_187.i -__barray_mask_borrow.exit289.i: ; preds = %__barray_check_bounds.exit284.i +__barray_mask_borrow.exit288.i: ; preds = %__barray_check_bounds.exit283.i %79 = xor i64 %76, %77 store i64 %79, i64* %75, align 4 - %80 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"162_0.0.i1" + %80 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"164_0.0.i1" %81 = load { i1, i64, i1 }, { i1, i64, i1 }* %80, align 4 - %.fca.0.extract180.i = extractvalue { i1, i64, i1 } %81, 0 - br i1 %.fca.0.extract180.i, label %cond_85_case_1.i, label %cond_exit_160.i + %.fca.0.extract179.i = extractvalue { i1, i64, i1 } %81, 0 + br i1 %.fca.0.extract179.i, label %cond_87_case_1.i, label %cond_exit_187.i -cond_exit_160.i: ; preds = %cond_85_case_1.i, %__barray_mask_borrow.exit289.i, %__barray_check_bounds.exit284.i - %82 = add nuw nsw i64 %"162_0.0.i1", 1 +cond_exit_187.i: ; preds = %cond_87_case_1.i, %__barray_mask_borrow.exit288.i, %__barray_check_bounds.exit283.i + %82 = add nuw nsw i64 %"164_0.0.i1", 1 %exitcond.not = icmp eq i64 %82, 10 - br i1 %exitcond.not, label %cond_160_case_0.i, label %__barray_check_bounds.exit284.i + br i1 %exitcond.not, label %cond_187_case_0.i, label %__barray_check_bounds.exit283.i -cond_85_case_1.i: ; preds = %__barray_mask_borrow.exit289.i +cond_87_case_1.i: ; preds = %__barray_mask_borrow.exit288.i %.fca.1.extract.i = extractvalue { i1, i64, i1 } %81, 1 tail call void @___dec_future_refcount(i64 %.fca.1.extract.i) - br label %cond_exit_160.i + br label %cond_exit_187.i -__hugr__.main.1.exit: ; preds = %cond_160_case_0.i +__hugr__.main.1.exit: ; preds = %cond_187_case_0.i tail call void @heap_free(i8* %49) tail call void @heap_free(i8* nonnull %51) %83 = tail call i64 @teardown() diff --git a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-apple-darwin-print_array/print_array_x86_64-apple-darwin b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-apple-darwin-print_array/print_array_x86_64-apple-darwin index 4c5d75106..7e5273479 100644 --- a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-apple-darwin-print_array/print_array_x86_64-apple-darwin +++ b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-apple-darwin-print_array/print_array_x86_64-apple-darwin @@ -34,8 +34,8 @@ alloca_block: br label %cond_20_case_1 cond_20_case_1: ; preds = %alloca_block, %cond_exit_20 - %"15_0.sroa.0.0961" = phi i64 [ 0, %alloca_block ], [ %12, %cond_exit_20 ] - %12 = add nuw nsw i64 %"15_0.sroa.0.0961", 1 + %"15_0.sroa.0.0955" = phi i64 [ 0, %alloca_block ], [ %12, %cond_exit_20 ] + %12 = add nuw nsw i64 %"15_0.sroa.0.0955", 1 %qalloc.i = tail call i64 @___qalloc() %not_max.not.i = icmp eq i64 %qalloc.i, -1 br i1 %not_max.not.i, label %id_bb.i, label %reset_bb.i @@ -55,10 +55,10 @@ cond_303_case_0.i: ; preds = %id_bb.i unreachable __barray_check_bounds.exit: ; preds = %id_bb.i - %15 = lshr i64 %"15_0.sroa.0.0961", 6 + %15 = lshr i64 %"15_0.sroa.0.0955", 6 %16 = getelementptr inbounds i64, i64* %11, i64 %15 %17 = load i64, i64* %16, align 4 - %18 = shl nuw nsw i64 1, %"15_0.sroa.0.0961" + %18 = shl nuw nsw i64 1, %"15_0.sroa.0.0955" %19 = and i64 %17, %18 %.not.i = icmp eq i64 %19, 0 br i1 %.not.i, label %panic.i, label %cond_exit_20 @@ -71,7 +71,7 @@ cond_exit_20: ; preds = %__barray_check_boun %.fca.1.extract.i = extractvalue { i1, i64 } %14, 1 %20 = xor i64 %17, %18 store i64 %20, i64* %16, align 4 - %21 = getelementptr inbounds i64, i64* %9, i64 %"15_0.sroa.0.0961" + %21 = getelementptr inbounds i64, i64* %9, i64 %"15_0.sroa.0.0955" store i64 %.fca.1.extract.i, i64* %21, align 4 %exitcond.not = icmp eq i64 %12, 10 br i1 %exitcond.not, label %loop_out, label %cond_20_case_1 @@ -79,10 +79,10 @@ cond_exit_20: ; preds = %__barray_check_boun loop_out: ; preds = %cond_exit_20 %22 = load i64, i64* %11, align 4 %23 = and i64 %22, 1 - %.not.i852 = icmp eq i64 %23, 0 - br i1 %.not.i852, label %__barray_mask_borrow.exit, label %panic.i853 + %.not.i846 = icmp eq i64 %23, 0 + br i1 %.not.i846, label %__barray_mask_borrow.exit, label %panic.i847 -panic.i853: ; preds = %loop_out +panic.i847: ; preds = %loop_out tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable @@ -93,27 +93,27 @@ __barray_mask_borrow.exit: ; preds = %loop_out tail call void @___rxy(i64 %25, double 0x400921FB54442D18, double 0.000000e+00) %26 = load i64, i64* %11, align 4 %27 = and i64 %26, 1 - %.not.i854 = icmp eq i64 %27, 0 - br i1 %.not.i854, label %panic.i855, label %__barray_mask_return.exit856 + %.not.i848 = icmp eq i64 %27, 0 + br i1 %.not.i848, label %panic.i849, label %__barray_mask_return.exit850 -panic.i855: ; preds = %__barray_mask_borrow.exit +panic.i849: ; preds = %__barray_mask_borrow.exit tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit856: ; preds = %__barray_mask_borrow.exit +__barray_mask_return.exit850: ; preds = %__barray_mask_borrow.exit %28 = xor i64 %26, 1 store i64 %28, i64* %11, align 4 store i64 %25, i64* %9, align 4 %29 = load i64, i64* %11, align 4 %30 = and i64 %29, 4 - %.not.i857 = icmp eq i64 %30, 0 - br i1 %.not.i857, label %__barray_mask_borrow.exit859, label %panic.i858 + %.not.i851 = icmp eq i64 %30, 0 + br i1 %.not.i851, label %__barray_mask_borrow.exit853, label %panic.i852 -panic.i858: ; preds = %__barray_mask_return.exit856 +panic.i852: ; preds = %__barray_mask_return.exit850 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit859: ; preds = %__barray_mask_return.exit856 +__barray_mask_borrow.exit853: ; preds = %__barray_mask_return.exit850 %31 = xor i64 %29, 4 store i64 %31, i64* %11, align 4 %32 = getelementptr inbounds i8, i8* %8, i64 16 @@ -122,27 +122,27 @@ __barray_mask_borrow.exit859: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %34, double 0x400921FB54442D18, double 0.000000e+00) %35 = load i64, i64* %11, align 4 %36 = and i64 %35, 4 - %.not.i860 = icmp eq i64 %36, 0 - br i1 %.not.i860, label %panic.i861, label %__barray_mask_return.exit862 + %.not.i854 = icmp eq i64 %36, 0 + br i1 %.not.i854, label %panic.i855, label %__barray_mask_return.exit856 -panic.i861: ; preds = %__barray_mask_borrow.exit859 +panic.i855: ; preds = %__barray_mask_borrow.exit853 tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit862: ; preds = %__barray_mask_borrow.exit859 +__barray_mask_return.exit856: ; preds = %__barray_mask_borrow.exit853 %37 = xor i64 %35, 4 store i64 %37, i64* %11, align 4 store i64 %34, i64* %33, align 4 %38 = load i64, i64* %11, align 4 %39 = and i64 %38, 8 - %.not.i863 = icmp eq i64 %39, 0 - br i1 %.not.i863, label %__barray_mask_borrow.exit865, label %panic.i864 + %.not.i857 = icmp eq i64 %39, 0 + br i1 %.not.i857, label %__barray_mask_borrow.exit859, label %panic.i858 -panic.i864: ; preds = %__barray_mask_return.exit862 +panic.i858: ; preds = %__barray_mask_return.exit856 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit865: ; preds = %__barray_mask_return.exit862 +__barray_mask_borrow.exit859: ; preds = %__barray_mask_return.exit856 %40 = xor i64 %38, 8 store i64 %40, i64* %11, align 4 %41 = getelementptr inbounds i8, i8* %8, i64 24 @@ -151,27 +151,27 @@ __barray_mask_borrow.exit865: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %43, double 0x400921FB54442D18, double 0.000000e+00) %44 = load i64, i64* %11, align 4 %45 = and i64 %44, 8 - %.not.i866 = icmp eq i64 %45, 0 - br i1 %.not.i866, label %panic.i867, label %__barray_mask_return.exit868 + %.not.i860 = icmp eq i64 %45, 0 + br i1 %.not.i860, label %panic.i861, label %__barray_mask_return.exit862 -panic.i867: ; preds = %__barray_mask_borrow.exit865 +panic.i861: ; preds = %__barray_mask_borrow.exit859 tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit868: ; preds = %__barray_mask_borrow.exit865 +__barray_mask_return.exit862: ; preds = %__barray_mask_borrow.exit859 %46 = xor i64 %44, 8 store i64 %46, i64* %11, align 4 store i64 %43, i64* %42, align 4 %47 = load i64, i64* %11, align 4 %48 = and i64 %47, 512 - %.not.i869 = icmp eq i64 %48, 0 - br i1 %.not.i869, label %__barray_mask_borrow.exit871, label %panic.i870 + %.not.i863 = icmp eq i64 %48, 0 + br i1 %.not.i863, label %__barray_mask_borrow.exit865, label %panic.i864 -panic.i870: ; preds = %__barray_mask_return.exit868 +panic.i864: ; preds = %__barray_mask_return.exit862 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit871: ; preds = %__barray_mask_return.exit868 +__barray_mask_borrow.exit865: ; preds = %__barray_mask_return.exit862 %49 = xor i64 %47, 512 store i64 %49, i64* %11, align 4 %50 = getelementptr inbounds i8, i8* %8, i64 72 @@ -180,14 +180,14 @@ __barray_mask_borrow.exit871: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %52, double 0x400921FB54442D18, double 0.000000e+00) %53 = load i64, i64* %11, align 4 %54 = and i64 %53, 512 - %.not.i872 = icmp eq i64 %54, 0 - br i1 %.not.i872, label %panic.i873, label %__barray_mask_return.exit874 + %.not.i866 = icmp eq i64 %54, 0 + br i1 %.not.i866, label %panic.i867, label %__barray_mask_return.exit868 -panic.i873: ; preds = %__barray_mask_borrow.exit871 +panic.i867: ; preds = %__barray_mask_borrow.exit865 tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit874: ; preds = %__barray_mask_borrow.exit871 +__barray_mask_return.exit868: ; preds = %__barray_mask_borrow.exit865 %55 = xor i64 %53, 512 store i64 %55, i64* %11, align 4 store i64 %52, i64* %51, align 4 @@ -223,13 +223,13 @@ mask_block_err.i.i.i: ; preds = %mask_block_ok.i.i.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -69: ; preds = %__barray_mask_return.exit874, %cond_exit_443.i - %"393_0.sroa.15.0.i963" = phi i64 [ 0, %__barray_mask_return.exit874 ], [ %70, %cond_exit_443.i ] - %70 = add nuw nsw i64 %"393_0.sroa.15.0.i963", 1 - %71 = lshr i64 %"393_0.sroa.15.0.i963", 6 +69: ; preds = %__barray_mask_return.exit868, %cond_exit_443.i + %"393_0.sroa.15.0.i957" = phi i64 [ 0, %__barray_mask_return.exit868 ], [ %70, %cond_exit_443.i ] + %70 = add nuw nsw i64 %"393_0.sroa.15.0.i957", 1 + %71 = lshr i64 %"393_0.sroa.15.0.i957", 6 %72 = getelementptr inbounds i64, i64* %11, i64 %71 %73 = load i64, i64* %72, align 4 - %74 = shl nuw nsw i64 1, %"393_0.sroa.15.0.i963" + %74 = shl nuw nsw i64 1, %"393_0.sroa.15.0.i957" %75 = and i64 %73, %74 %.not.i99.i.i = icmp eq i64 %75, 0 br i1 %.not.i99.i.i, label %__barray_check_bounds.exit.i, label %panic.i.i.i @@ -241,7 +241,7 @@ panic.i.i.i: ; preds = %69 __barray_check_bounds.exit.i: ; preds = %69 %76 = xor i64 %73, %74 store i64 %76, i64* %72, align 4 - %77 = getelementptr inbounds i64, i64* %9, i64 %"393_0.sroa.15.0.i963" + %77 = getelementptr inbounds i64, i64* %9, i64 %"393_0.sroa.15.0.i957" %78 = load i64, i64* %77, align 4 %lazy_measure.i = tail call i64 @___lazy_measure(i64 %78) tail call void @___qfree(i64 %78) @@ -259,10 +259,10 @@ cond_exit_443.i: ; preds = %__barray_check_boun %"457_054.fca.1.insert.i" = insertvalue { i1, i64, i1 } { i1 true, i64 poison, i1 poison }, i64 %lazy_measure.i, 1 %82 = xor i64 %80, %74 store i64 %82, i64* %79, align 4 - %83 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %"393_0.sroa.15.0.i963" + %83 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %"393_0.sroa.15.0.i957" store { i1, i64, i1 } %"457_054.fca.1.insert.i", { i1, i64, i1 }* %83, align 4 - %exitcond979.not = icmp eq i64 %70, 10 - br i1 %exitcond979.not, label %mask_block_ok.i.i.i, label %69 + %exitcond973.not = icmp eq i64 %70, 10 + br i1 %exitcond973.not, label %mask_block_ok.i.i.i, label %69 __barray_check_none_borrowed.exit: ; preds = %"__hugr__.$measure_array$$n(10).367.exit" %84 = tail call i8* @heap_alloc(i64 240) @@ -277,78 +277,78 @@ mask_block_err.i: ; preds = %"__hugr__.$measure_ tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -89: ; preds = %__barray_check_none_borrowed.exit, %__hugr__.const_fun_290.309.exit - %storemerge850968 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %107, %__hugr__.const_fun_290.309.exit ] - %90 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %105, %__hugr__.const_fun_290.309.exit ] - %91 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %storemerge850968 +89: ; preds = %__barray_check_none_borrowed.exit, %__hugr__.const_fun_338.322.exit + %storemerge844962 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %107, %__hugr__.const_fun_338.322.exit ] + %90 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %105, %__hugr__.const_fun_338.322.exit ] + %91 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %storemerge844962 %92 = load { i1, i64, i1 }, { i1, i64, i1 }* %91, align 4 %.fca.0.extract118.i = extractvalue { i1, i64, i1 } %92, 0 %.fca.1.extract119.i = extractvalue { i1, i64, i1 } %92, 1 - br i1 %.fca.0.extract118.i, label %cond_525_case_1.i, label %cond_exit_525.i + br i1 %.fca.0.extract118.i, label %cond_513_case_1.i, label %cond_exit_513.i -cond_525_case_1.i: ; preds = %89 +cond_513_case_1.i: ; preds = %89 tail call void @___inc_future_refcount(i64 %.fca.1.extract119.i) %93 = insertvalue { i1, i64, i1 } { i1 true, i64 poison, i1 poison }, i64 %.fca.1.extract119.i, 1 - br label %cond_exit_525.i + br label %cond_exit_513.i -cond_exit_525.i: ; preds = %cond_525_case_1.i, %89 - %.pn.i = phi { i1, i64, i1 } [ %93, %cond_525_case_1.i ], [ %92, %89 ] +cond_exit_513.i: ; preds = %cond_513_case_1.i, %89 + %.pn.i = phi { i1, i64, i1 } [ %93, %cond_513_case_1.i ], [ %92, %89 ] %"04.sroa.6.0.i" = extractvalue { i1, i64, i1 } %.pn.i, 2 %94 = icmp ult i64 %90, 10 - br i1 %94, label %95, label %cond_528_case_0.i + br i1 %94, label %95, label %cond_516_case_0.i -95: ; preds = %cond_exit_525.i +95: ; preds = %cond_exit_513.i %96 = lshr i64 %90, 6 %97 = getelementptr inbounds i64, i64* %65, i64 %96 %98 = load i64, i64* %97, align 4 %99 = shl nuw nsw i64 1, %90 %100 = and i64 %98, %99 - %.not.i.i876 = icmp eq i64 %100, 0 - br i1 %.not.i.i876, label %cond_528_case_1.i, label %panic.i.i877 + %.not.i.i870 = icmp eq i64 %100, 0 + br i1 %.not.i.i870, label %cond_516_case_1.i, label %panic.i.i871 -panic.i.i877: ; preds = %95 +panic.i.i871: ; preds = %95 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -cond_528_case_0.i: ; preds = %cond_exit_525.i +cond_516_case_0.i: ; preds = %cond_exit_513.i tail call void @panic(i32 1001, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @"e_Expected v.E6312129.0", i64 0, i64 0)) unreachable -cond_528_case_1.i: ; preds = %95 +cond_516_case_1.i: ; preds = %95 %"17.fca.2.insert.i" = insertvalue { i1, i64, i1 } %92, i1 %"04.sroa.6.0.i", 2 %101 = insertvalue { i1, { i1, i64, i1 } } { i1 true, { i1, i64, i1 } poison }, { i1, i64, i1 } %"17.fca.2.insert.i", 1 %102 = getelementptr inbounds { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %88, i64 %90 %103 = getelementptr inbounds { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %102, i64 0, i32 0 %104 = load i1, i1* %103, align 1 store { i1, { i1, i64, i1 } } %101, { i1, { i1, i64, i1 } }* %102, align 4 - br i1 %104, label %cond_529_case_1.i, label %__hugr__.const_fun_290.309.exit + br i1 %104, label %cond_517_case_1.i, label %__hugr__.const_fun_338.322.exit -cond_529_case_1.i: ; preds = %cond_528_case_1.i +cond_517_case_1.i: ; preds = %cond_516_case_1.i tail call void @panic(i32 1001, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @"e_Expected v.2F17E0A9.0", i64 0, i64 0)) unreachable -__hugr__.const_fun_290.309.exit: ; preds = %cond_528_case_1.i +__hugr__.const_fun_338.322.exit: ; preds = %cond_516_case_1.i %105 = add nuw nsw i64 %90, 1 - %106 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %85, i64 %storemerge850968 + %106 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %85, i64 %storemerge844962 store { i1, i64, i1 } %"17.fca.2.insert.i", { i1, i64, i1 }* %106, align 4 - %107 = add nuw nsw i64 %storemerge850968, 1 - %exitcond980.not = icmp eq i64 %107, 10 - br i1 %exitcond980.not, label %mask_block_ok.i881, label %89 + %107 = add nuw nsw i64 %storemerge844962, 1 + %exitcond974.not = icmp eq i64 %107, 10 + br i1 %exitcond974.not, label %mask_block_ok.i875, label %89 -mask_block_ok.i881: ; preds = %__hugr__.const_fun_290.309.exit +mask_block_ok.i875: ; preds = %__hugr__.const_fun_338.322.exit tail call void @heap_free(i8* nonnull %56) tail call void @heap_free(i8* %58) %108 = load i64, i64* %65, align 4 %109 = and i64 %108, 1023 store i64 %109, i64* %65, align 4 %110 = icmp eq i64 %109, 0 - br i1 %110, label %__barray_check_none_borrowed.exit883, label %mask_block_err.i882 + br i1 %110, label %__barray_check_none_borrowed.exit877, label %mask_block_err.i876 -mask_block_err.i882: ; preds = %mask_block_ok.i881 +mask_block_err.i876: ; preds = %mask_block_ok.i875 tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_none_borrowed.exit883: ; preds = %mask_block_ok.i881 +__barray_check_none_borrowed.exit877: ; preds = %mask_block_ok.i875 %111 = tail call i8* @heap_alloc(i64 240) %112 = bitcast i8* %111 to { i1, i64, i1 }* %113 = tail call i8* @heap_alloc(i64 8) @@ -356,22 +356,22 @@ __barray_check_none_borrowed.exit883: ; preds = %mask_block_ok.i881 store i64 0, i64* %114, align 1 %115 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %88, align 4 %.fca.0.extract11.i = extractvalue { i1, { i1, i64, i1 } } %115, 0 - br i1 %.fca.0.extract11.i, label %__hugr__.const_fun_284.290.exit, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i, label %__hugr__.const_fun_287.338.exit, label %cond_558_case_0.i -cond_570_case_0.i: ; preds = %__hugr__.const_fun_284.290.exit.8, %__hugr__.const_fun_284.290.exit.7, %__hugr__.const_fun_284.290.exit.6, %__hugr__.const_fun_284.290.exit.5, %__hugr__.const_fun_284.290.exit.4, %__hugr__.const_fun_284.290.exit.3, %__hugr__.const_fun_284.290.exit.2, %__hugr__.const_fun_284.290.exit.1, %__hugr__.const_fun_284.290.exit, %__barray_check_none_borrowed.exit883 +cond_558_case_0.i: ; preds = %__hugr__.const_fun_287.338.exit.8, %__hugr__.const_fun_287.338.exit.7, %__hugr__.const_fun_287.338.exit.6, %__hugr__.const_fun_287.338.exit.5, %__hugr__.const_fun_287.338.exit.4, %__hugr__.const_fun_287.338.exit.3, %__hugr__.const_fun_287.338.exit.2, %__hugr__.const_fun_287.338.exit.1, %__hugr__.const_fun_287.338.exit, %__barray_check_none_borrowed.exit877 tail call void @panic(i32 1001, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @"e_Expected v.E6312129.0", i64 0, i64 0)) unreachable -__hugr__.const_fun_284.290.exit: ; preds = %__barray_check_none_borrowed.exit883 +__hugr__.const_fun_287.338.exit: ; preds = %__barray_check_none_borrowed.exit877 %116 = extractvalue { i1, { i1, i64, i1 } } %115, 1 store { i1, i64, i1 } %116, { i1, i64, i1 }* %112, align 4 %117 = getelementptr inbounds i8, i8* %63, i64 32 %118 = bitcast i8* %117 to { i1, { i1, i64, i1 } }* %119 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %118, align 4 %.fca.0.extract11.i.1 = extractvalue { i1, { i1, i64, i1 } } %119, 0 - br i1 %.fca.0.extract11.i.1, label %__hugr__.const_fun_284.290.exit.1, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.1, label %__hugr__.const_fun_287.338.exit.1, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.1: ; preds = %__hugr__.const_fun_284.290.exit +__hugr__.const_fun_287.338.exit.1: ; preds = %__hugr__.const_fun_287.338.exit %120 = extractvalue { i1, { i1, i64, i1 } } %119, 1 %121 = getelementptr inbounds i8, i8* %111, i64 24 %122 = bitcast i8* %121 to { i1, i64, i1 }* @@ -380,9 +380,9 @@ __hugr__.const_fun_284.290.exit.1: ; preds = %__hugr__.const_fun_ %124 = bitcast i8* %123 to { i1, { i1, i64, i1 } }* %125 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %124, align 4 %.fca.0.extract11.i.2 = extractvalue { i1, { i1, i64, i1 } } %125, 0 - br i1 %.fca.0.extract11.i.2, label %__hugr__.const_fun_284.290.exit.2, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.2, label %__hugr__.const_fun_287.338.exit.2, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.2: ; preds = %__hugr__.const_fun_284.290.exit.1 +__hugr__.const_fun_287.338.exit.2: ; preds = %__hugr__.const_fun_287.338.exit.1 %126 = extractvalue { i1, { i1, i64, i1 } } %125, 1 %127 = getelementptr inbounds i8, i8* %111, i64 48 %128 = bitcast i8* %127 to { i1, i64, i1 }* @@ -391,9 +391,9 @@ __hugr__.const_fun_284.290.exit.2: ; preds = %__hugr__.const_fun_ %130 = bitcast i8* %129 to { i1, { i1, i64, i1 } }* %131 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %130, align 4 %.fca.0.extract11.i.3 = extractvalue { i1, { i1, i64, i1 } } %131, 0 - br i1 %.fca.0.extract11.i.3, label %__hugr__.const_fun_284.290.exit.3, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.3, label %__hugr__.const_fun_287.338.exit.3, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.3: ; preds = %__hugr__.const_fun_284.290.exit.2 +__hugr__.const_fun_287.338.exit.3: ; preds = %__hugr__.const_fun_287.338.exit.2 %132 = extractvalue { i1, { i1, i64, i1 } } %131, 1 %133 = getelementptr inbounds i8, i8* %111, i64 72 %134 = bitcast i8* %133 to { i1, i64, i1 }* @@ -402,9 +402,9 @@ __hugr__.const_fun_284.290.exit.3: ; preds = %__hugr__.const_fun_ %136 = bitcast i8* %135 to { i1, { i1, i64, i1 } }* %137 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %136, align 4 %.fca.0.extract11.i.4 = extractvalue { i1, { i1, i64, i1 } } %137, 0 - br i1 %.fca.0.extract11.i.4, label %__hugr__.const_fun_284.290.exit.4, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.4, label %__hugr__.const_fun_287.338.exit.4, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.4: ; preds = %__hugr__.const_fun_284.290.exit.3 +__hugr__.const_fun_287.338.exit.4: ; preds = %__hugr__.const_fun_287.338.exit.3 %138 = extractvalue { i1, { i1, i64, i1 } } %137, 1 %139 = getelementptr inbounds i8, i8* %111, i64 96 %140 = bitcast i8* %139 to { i1, i64, i1 }* @@ -413,9 +413,9 @@ __hugr__.const_fun_284.290.exit.4: ; preds = %__hugr__.const_fun_ %142 = bitcast i8* %141 to { i1, { i1, i64, i1 } }* %143 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %142, align 4 %.fca.0.extract11.i.5 = extractvalue { i1, { i1, i64, i1 } } %143, 0 - br i1 %.fca.0.extract11.i.5, label %__hugr__.const_fun_284.290.exit.5, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.5, label %__hugr__.const_fun_287.338.exit.5, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.5: ; preds = %__hugr__.const_fun_284.290.exit.4 +__hugr__.const_fun_287.338.exit.5: ; preds = %__hugr__.const_fun_287.338.exit.4 %144 = extractvalue { i1, { i1, i64, i1 } } %143, 1 %145 = getelementptr inbounds i8, i8* %111, i64 120 %146 = bitcast i8* %145 to { i1, i64, i1 }* @@ -424,9 +424,9 @@ __hugr__.const_fun_284.290.exit.5: ; preds = %__hugr__.const_fun_ %148 = bitcast i8* %147 to { i1, { i1, i64, i1 } }* %149 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %148, align 4 %.fca.0.extract11.i.6 = extractvalue { i1, { i1, i64, i1 } } %149, 0 - br i1 %.fca.0.extract11.i.6, label %__hugr__.const_fun_284.290.exit.6, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.6, label %__hugr__.const_fun_287.338.exit.6, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.6: ; preds = %__hugr__.const_fun_284.290.exit.5 +__hugr__.const_fun_287.338.exit.6: ; preds = %__hugr__.const_fun_287.338.exit.5 %150 = extractvalue { i1, { i1, i64, i1 } } %149, 1 %151 = getelementptr inbounds i8, i8* %111, i64 144 %152 = bitcast i8* %151 to { i1, i64, i1 }* @@ -435,9 +435,9 @@ __hugr__.const_fun_284.290.exit.6: ; preds = %__hugr__.const_fun_ %154 = bitcast i8* %153 to { i1, { i1, i64, i1 } }* %155 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %154, align 4 %.fca.0.extract11.i.7 = extractvalue { i1, { i1, i64, i1 } } %155, 0 - br i1 %.fca.0.extract11.i.7, label %__hugr__.const_fun_284.290.exit.7, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.7, label %__hugr__.const_fun_287.338.exit.7, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.7: ; preds = %__hugr__.const_fun_284.290.exit.6 +__hugr__.const_fun_287.338.exit.7: ; preds = %__hugr__.const_fun_287.338.exit.6 %156 = extractvalue { i1, { i1, i64, i1 } } %155, 1 %157 = getelementptr inbounds i8, i8* %111, i64 168 %158 = bitcast i8* %157 to { i1, i64, i1 }* @@ -446,9 +446,9 @@ __hugr__.const_fun_284.290.exit.7: ; preds = %__hugr__.const_fun_ %160 = bitcast i8* %159 to { i1, { i1, i64, i1 } }* %161 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %160, align 4 %.fca.0.extract11.i.8 = extractvalue { i1, { i1, i64, i1 } } %161, 0 - br i1 %.fca.0.extract11.i.8, label %__hugr__.const_fun_284.290.exit.8, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.8, label %__hugr__.const_fun_287.338.exit.8, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.8: ; preds = %__hugr__.const_fun_284.290.exit.7 +__hugr__.const_fun_287.338.exit.8: ; preds = %__hugr__.const_fun_287.338.exit.7 %162 = extractvalue { i1, { i1, i64, i1 } } %161, 1 %163 = getelementptr inbounds i8, i8* %111, i64 192 %164 = bitcast i8* %163 to { i1, i64, i1 }* @@ -457,86 +457,86 @@ __hugr__.const_fun_284.290.exit.8: ; preds = %__hugr__.const_fun_ %166 = bitcast i8* %165 to { i1, { i1, i64, i1 } }* %167 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %166, align 4 %.fca.0.extract11.i.9 = extractvalue { i1, { i1, i64, i1 } } %167, 0 - br i1 %.fca.0.extract11.i.9, label %__hugr__.const_fun_284.290.exit.9, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.9, label %__hugr__.const_fun_287.338.exit.9, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.9: ; preds = %__hugr__.const_fun_284.290.exit.8 +__hugr__.const_fun_287.338.exit.9: ; preds = %__hugr__.const_fun_287.338.exit.8 %168 = extractvalue { i1, { i1, i64, i1 } } %167, 1 %169 = getelementptr inbounds i8, i8* %111, i64 216 %170 = bitcast i8* %169 to { i1, i64, i1 }* store { i1, i64, i1 } %168, { i1, i64, i1 }* %170, align 4 tail call void @heap_free(i8* nonnull %63) tail call void @heap_free(i8* nonnull %64) - br label %__barray_check_bounds.exit888 + br label %__barray_check_bounds.exit882 -cond_165_case_0: ; preds = %cond_exit_165 +cond_169_case_0: ; preds = %cond_exit_169 %171 = load i64, i64* %114, align 4 %172 = or i64 %171, -1024 store i64 %172, i64* %114, align 4 %173 = icmp eq i64 %172, -1 - br i1 %173, label %loop_out139, label %mask_block_err.i886 + br i1 %173, label %loop_out135, label %mask_block_err.i880 -mask_block_err.i886: ; preds = %cond_165_case_0 +mask_block_err.i880: ; preds = %cond_169_case_0 tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit888: ; preds = %__hugr__.const_fun_284.290.exit.9, %cond_exit_165 - %"167_0.0989" = phi i64 [ 0, %__hugr__.const_fun_284.290.exit.9 ], [ %174, %cond_exit_165 ] - %174 = add nuw nsw i64 %"167_0.0989", 1 - %175 = lshr i64 %"167_0.0989", 6 +__barray_check_bounds.exit882: ; preds = %__hugr__.const_fun_287.338.exit.9, %cond_exit_169 + %"172_0.0983" = phi i64 [ 0, %__hugr__.const_fun_287.338.exit.9 ], [ %174, %cond_exit_169 ] + %174 = add nuw nsw i64 %"172_0.0983", 1 + %175 = lshr i64 %"172_0.0983", 6 %176 = getelementptr inbounds i64, i64* %114, i64 %175 %177 = load i64, i64* %176, align 4 - %178 = shl nuw nsw i64 1, %"167_0.0989" + %178 = shl nuw nsw i64 1, %"172_0.0983" %179 = and i64 %177, %178 %.not = icmp eq i64 %179, 0 - br i1 %.not, label %__barray_mask_borrow.exit893, label %cond_exit_165 + br i1 %.not, label %__barray_mask_borrow.exit887, label %cond_exit_169 -__barray_mask_borrow.exit893: ; preds = %__barray_check_bounds.exit888 +__barray_mask_borrow.exit887: ; preds = %__barray_check_bounds.exit882 %180 = xor i64 %177, %178 store i64 %180, i64* %176, align 4 - %181 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %112, i64 %"167_0.0989" + %181 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %112, i64 %"172_0.0983" %182 = load { i1, i64, i1 }, { i1, i64, i1 }* %181, align 4 - %.fca.0.extract511 = extractvalue { i1, i64, i1 } %182, 0 - br i1 %.fca.0.extract511, label %cond_501_case_1, label %cond_exit_165 + %.fca.0.extract505 = extractvalue { i1, i64, i1 } %182, 0 + br i1 %.fca.0.extract505, label %cond_496_case_1, label %cond_exit_169 -cond_exit_165: ; preds = %cond_501_case_1, %__barray_mask_borrow.exit893, %__barray_check_bounds.exit888 - %183 = icmp ult i64 %"167_0.0989", 9 - br i1 %183, label %__barray_check_bounds.exit888, label %cond_165_case_0 +cond_exit_169: ; preds = %cond_496_case_1, %__barray_mask_borrow.exit887, %__barray_check_bounds.exit882 + %183 = icmp ult i64 %"172_0.0983", 9 + br i1 %183, label %__barray_check_bounds.exit882, label %cond_169_case_0 -loop_out139: ; preds = %cond_165_case_0 +loop_out135: ; preds = %cond_169_case_0 tail call void @heap_free(i8* %111) tail call void @heap_free(i8* nonnull %113) %184 = load i64, i64* %87, align 4 %185 = and i64 %184, 1023 store i64 %185, i64* %87, align 4 %186 = icmp eq i64 %185, 0 - br i1 %186, label %__barray_check_none_borrowed.exit898, label %mask_block_err.i897 + br i1 %186, label %__barray_check_none_borrowed.exit892, label %mask_block_err.i891 -__barray_check_none_borrowed.exit898: ; preds = %loop_out139 +__barray_check_none_borrowed.exit892: ; preds = %loop_out135 %187 = tail call i8* @heap_alloc(i64 10) %188 = tail call i8* @heap_alloc(i64 8) %189 = bitcast i8* %188 to i64* store i64 0, i64* %189, align 1 %190 = load { i1, i64, i1 }, { i1, i64, i1 }* %85, align 4 - %.fca.0.extract.i899 = extractvalue { i1, i64, i1 } %190, 0 - %.fca.1.extract.i900 = extractvalue { i1, i64, i1 } %190, 1 - br i1 %.fca.0.extract.i899, label %cond_300_case_1.i, label %cond_300_case_0.i + %.fca.0.extract.i893 = extractvalue { i1, i64, i1 } %190, 0 + %.fca.1.extract.i894 = extractvalue { i1, i64, i1 } %190, 1 + br i1 %.fca.0.extract.i893, label %cond_300_case_1.i, label %cond_300_case_0.i -mask_block_err.i897: ; preds = %loop_out139 +mask_block_err.i891: ; preds = %loop_out135 tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -cond_501_case_1: ; preds = %__barray_mask_borrow.exit893 - %.fca.1.extract512 = extractvalue { i1, i64, i1 } %182, 1 - tail call void @___dec_future_refcount(i64 %.fca.1.extract512) - br label %cond_exit_165 +cond_496_case_1: ; preds = %__barray_mask_borrow.exit887 + %.fca.1.extract506 = extractvalue { i1, i64, i1 } %182, 1 + tail call void @___dec_future_refcount(i64 %.fca.1.extract506) + br label %cond_exit_169 -cond_300_case_0.i: ; preds = %__barray_check_none_borrowed.exit898 +cond_300_case_0.i: ; preds = %__barray_check_none_borrowed.exit892 %.fca.2.extract.i = extractvalue { i1, i64, i1 } %190, 2 br label %__hugr__.array.__read_bool.3.271.exit -cond_300_case_1.i: ; preds = %__barray_check_none_borrowed.exit898 - %read_bool.i = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900) +cond_300_case_1.i: ; preds = %__barray_check_none_borrowed.exit892 + %read_bool.i = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894) br label %__hugr__.array.__read_bool.3.271.exit __hugr__.array.__read_bool.3.271.exit: ; preds = %cond_300_case_0.i, %cond_300_case_1.i @@ -546,17 +546,17 @@ __hugr__.array.__read_bool.3.271.exit: ; preds = %cond_300_case_0.i, %192 = getelementptr inbounds i8, i8* %84, i64 24 %193 = bitcast i8* %192 to { i1, i64, i1 }* %194 = load { i1, i64, i1 }, { i1, i64, i1 }* %193, align 4 - %.fca.0.extract.i899.1 = extractvalue { i1, i64, i1 } %194, 0 - %.fca.1.extract.i900.1 = extractvalue { i1, i64, i1 } %194, 1 - br i1 %.fca.0.extract.i899.1, label %cond_300_case_1.i.1, label %cond_300_case_0.i.1 + %.fca.0.extract.i893.1 = extractvalue { i1, i64, i1 } %194, 0 + %.fca.1.extract.i894.1 = extractvalue { i1, i64, i1 } %194, 1 + br i1 %.fca.0.extract.i893.1, label %cond_300_case_1.i.1, label %cond_300_case_0.i.1 cond_300_case_0.i.1: ; preds = %__hugr__.array.__read_bool.3.271.exit %.fca.2.extract.i.1 = extractvalue { i1, i64, i1 } %194, 2 br label %__hugr__.array.__read_bool.3.271.exit.1 cond_300_case_1.i.1: ; preds = %__hugr__.array.__read_bool.3.271.exit - %read_bool.i.1 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.1) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.1) + %read_bool.i.1 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.1) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.1) br label %__hugr__.array.__read_bool.3.271.exit.1 __hugr__.array.__read_bool.3.271.exit.1: ; preds = %cond_300_case_1.i.1, %cond_300_case_0.i.1 @@ -567,17 +567,17 @@ __hugr__.array.__read_bool.3.271.exit.1: ; preds = %cond_300_case_1.i.1 %197 = getelementptr inbounds i8, i8* %84, i64 48 %198 = bitcast i8* %197 to { i1, i64, i1 }* %199 = load { i1, i64, i1 }, { i1, i64, i1 }* %198, align 4 - %.fca.0.extract.i899.2 = extractvalue { i1, i64, i1 } %199, 0 - %.fca.1.extract.i900.2 = extractvalue { i1, i64, i1 } %199, 1 - br i1 %.fca.0.extract.i899.2, label %cond_300_case_1.i.2, label %cond_300_case_0.i.2 + %.fca.0.extract.i893.2 = extractvalue { i1, i64, i1 } %199, 0 + %.fca.1.extract.i894.2 = extractvalue { i1, i64, i1 } %199, 1 + br i1 %.fca.0.extract.i893.2, label %cond_300_case_1.i.2, label %cond_300_case_0.i.2 cond_300_case_0.i.2: ; preds = %__hugr__.array.__read_bool.3.271.exit.1 %.fca.2.extract.i.2 = extractvalue { i1, i64, i1 } %199, 2 br label %__hugr__.array.__read_bool.3.271.exit.2 cond_300_case_1.i.2: ; preds = %__hugr__.array.__read_bool.3.271.exit.1 - %read_bool.i.2 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.2) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.2) + %read_bool.i.2 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.2) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.2) br label %__hugr__.array.__read_bool.3.271.exit.2 __hugr__.array.__read_bool.3.271.exit.2: ; preds = %cond_300_case_1.i.2, %cond_300_case_0.i.2 @@ -588,17 +588,17 @@ __hugr__.array.__read_bool.3.271.exit.2: ; preds = %cond_300_case_1.i.2 %202 = getelementptr inbounds i8, i8* %84, i64 72 %203 = bitcast i8* %202 to { i1, i64, i1 }* %204 = load { i1, i64, i1 }, { i1, i64, i1 }* %203, align 4 - %.fca.0.extract.i899.3 = extractvalue { i1, i64, i1 } %204, 0 - %.fca.1.extract.i900.3 = extractvalue { i1, i64, i1 } %204, 1 - br i1 %.fca.0.extract.i899.3, label %cond_300_case_1.i.3, label %cond_300_case_0.i.3 + %.fca.0.extract.i893.3 = extractvalue { i1, i64, i1 } %204, 0 + %.fca.1.extract.i894.3 = extractvalue { i1, i64, i1 } %204, 1 + br i1 %.fca.0.extract.i893.3, label %cond_300_case_1.i.3, label %cond_300_case_0.i.3 cond_300_case_0.i.3: ; preds = %__hugr__.array.__read_bool.3.271.exit.2 %.fca.2.extract.i.3 = extractvalue { i1, i64, i1 } %204, 2 br label %__hugr__.array.__read_bool.3.271.exit.3 cond_300_case_1.i.3: ; preds = %__hugr__.array.__read_bool.3.271.exit.2 - %read_bool.i.3 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.3) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.3) + %read_bool.i.3 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.3) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.3) br label %__hugr__.array.__read_bool.3.271.exit.3 __hugr__.array.__read_bool.3.271.exit.3: ; preds = %cond_300_case_1.i.3, %cond_300_case_0.i.3 @@ -609,17 +609,17 @@ __hugr__.array.__read_bool.3.271.exit.3: ; preds = %cond_300_case_1.i.3 %207 = getelementptr inbounds i8, i8* %84, i64 96 %208 = bitcast i8* %207 to { i1, i64, i1 }* %209 = load { i1, i64, i1 }, { i1, i64, i1 }* %208, align 4 - %.fca.0.extract.i899.4 = extractvalue { i1, i64, i1 } %209, 0 - %.fca.1.extract.i900.4 = extractvalue { i1, i64, i1 } %209, 1 - br i1 %.fca.0.extract.i899.4, label %cond_300_case_1.i.4, label %cond_300_case_0.i.4 + %.fca.0.extract.i893.4 = extractvalue { i1, i64, i1 } %209, 0 + %.fca.1.extract.i894.4 = extractvalue { i1, i64, i1 } %209, 1 + br i1 %.fca.0.extract.i893.4, label %cond_300_case_1.i.4, label %cond_300_case_0.i.4 cond_300_case_0.i.4: ; preds = %__hugr__.array.__read_bool.3.271.exit.3 %.fca.2.extract.i.4 = extractvalue { i1, i64, i1 } %209, 2 br label %__hugr__.array.__read_bool.3.271.exit.4 cond_300_case_1.i.4: ; preds = %__hugr__.array.__read_bool.3.271.exit.3 - %read_bool.i.4 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.4) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.4) + %read_bool.i.4 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.4) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.4) br label %__hugr__.array.__read_bool.3.271.exit.4 __hugr__.array.__read_bool.3.271.exit.4: ; preds = %cond_300_case_1.i.4, %cond_300_case_0.i.4 @@ -630,17 +630,17 @@ __hugr__.array.__read_bool.3.271.exit.4: ; preds = %cond_300_case_1.i.4 %212 = getelementptr inbounds i8, i8* %84, i64 120 %213 = bitcast i8* %212 to { i1, i64, i1 }* %214 = load { i1, i64, i1 }, { i1, i64, i1 }* %213, align 4 - %.fca.0.extract.i899.5 = extractvalue { i1, i64, i1 } %214, 0 - %.fca.1.extract.i900.5 = extractvalue { i1, i64, i1 } %214, 1 - br i1 %.fca.0.extract.i899.5, label %cond_300_case_1.i.5, label %cond_300_case_0.i.5 + %.fca.0.extract.i893.5 = extractvalue { i1, i64, i1 } %214, 0 + %.fca.1.extract.i894.5 = extractvalue { i1, i64, i1 } %214, 1 + br i1 %.fca.0.extract.i893.5, label %cond_300_case_1.i.5, label %cond_300_case_0.i.5 cond_300_case_0.i.5: ; preds = %__hugr__.array.__read_bool.3.271.exit.4 %.fca.2.extract.i.5 = extractvalue { i1, i64, i1 } %214, 2 br label %__hugr__.array.__read_bool.3.271.exit.5 cond_300_case_1.i.5: ; preds = %__hugr__.array.__read_bool.3.271.exit.4 - %read_bool.i.5 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.5) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.5) + %read_bool.i.5 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.5) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.5) br label %__hugr__.array.__read_bool.3.271.exit.5 __hugr__.array.__read_bool.3.271.exit.5: ; preds = %cond_300_case_1.i.5, %cond_300_case_0.i.5 @@ -651,17 +651,17 @@ __hugr__.array.__read_bool.3.271.exit.5: ; preds = %cond_300_case_1.i.5 %217 = getelementptr inbounds i8, i8* %84, i64 144 %218 = bitcast i8* %217 to { i1, i64, i1 }* %219 = load { i1, i64, i1 }, { i1, i64, i1 }* %218, align 4 - %.fca.0.extract.i899.6 = extractvalue { i1, i64, i1 } %219, 0 - %.fca.1.extract.i900.6 = extractvalue { i1, i64, i1 } %219, 1 - br i1 %.fca.0.extract.i899.6, label %cond_300_case_1.i.6, label %cond_300_case_0.i.6 + %.fca.0.extract.i893.6 = extractvalue { i1, i64, i1 } %219, 0 + %.fca.1.extract.i894.6 = extractvalue { i1, i64, i1 } %219, 1 + br i1 %.fca.0.extract.i893.6, label %cond_300_case_1.i.6, label %cond_300_case_0.i.6 cond_300_case_0.i.6: ; preds = %__hugr__.array.__read_bool.3.271.exit.5 %.fca.2.extract.i.6 = extractvalue { i1, i64, i1 } %219, 2 br label %__hugr__.array.__read_bool.3.271.exit.6 cond_300_case_1.i.6: ; preds = %__hugr__.array.__read_bool.3.271.exit.5 - %read_bool.i.6 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.6) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.6) + %read_bool.i.6 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.6) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.6) br label %__hugr__.array.__read_bool.3.271.exit.6 __hugr__.array.__read_bool.3.271.exit.6: ; preds = %cond_300_case_1.i.6, %cond_300_case_0.i.6 @@ -672,17 +672,17 @@ __hugr__.array.__read_bool.3.271.exit.6: ; preds = %cond_300_case_1.i.6 %222 = getelementptr inbounds i8, i8* %84, i64 168 %223 = bitcast i8* %222 to { i1, i64, i1 }* %224 = load { i1, i64, i1 }, { i1, i64, i1 }* %223, align 4 - %.fca.0.extract.i899.7 = extractvalue { i1, i64, i1 } %224, 0 - %.fca.1.extract.i900.7 = extractvalue { i1, i64, i1 } %224, 1 - br i1 %.fca.0.extract.i899.7, label %cond_300_case_1.i.7, label %cond_300_case_0.i.7 + %.fca.0.extract.i893.7 = extractvalue { i1, i64, i1 } %224, 0 + %.fca.1.extract.i894.7 = extractvalue { i1, i64, i1 } %224, 1 + br i1 %.fca.0.extract.i893.7, label %cond_300_case_1.i.7, label %cond_300_case_0.i.7 cond_300_case_0.i.7: ; preds = %__hugr__.array.__read_bool.3.271.exit.6 %.fca.2.extract.i.7 = extractvalue { i1, i64, i1 } %224, 2 br label %__hugr__.array.__read_bool.3.271.exit.7 cond_300_case_1.i.7: ; preds = %__hugr__.array.__read_bool.3.271.exit.6 - %read_bool.i.7 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.7) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.7) + %read_bool.i.7 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.7) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.7) br label %__hugr__.array.__read_bool.3.271.exit.7 __hugr__.array.__read_bool.3.271.exit.7: ; preds = %cond_300_case_1.i.7, %cond_300_case_0.i.7 @@ -693,17 +693,17 @@ __hugr__.array.__read_bool.3.271.exit.7: ; preds = %cond_300_case_1.i.7 %227 = getelementptr inbounds i8, i8* %84, i64 192 %228 = bitcast i8* %227 to { i1, i64, i1 }* %229 = load { i1, i64, i1 }, { i1, i64, i1 }* %228, align 4 - %.fca.0.extract.i899.8 = extractvalue { i1, i64, i1 } %229, 0 - %.fca.1.extract.i900.8 = extractvalue { i1, i64, i1 } %229, 1 - br i1 %.fca.0.extract.i899.8, label %cond_300_case_1.i.8, label %cond_300_case_0.i.8 + %.fca.0.extract.i893.8 = extractvalue { i1, i64, i1 } %229, 0 + %.fca.1.extract.i894.8 = extractvalue { i1, i64, i1 } %229, 1 + br i1 %.fca.0.extract.i893.8, label %cond_300_case_1.i.8, label %cond_300_case_0.i.8 cond_300_case_0.i.8: ; preds = %__hugr__.array.__read_bool.3.271.exit.7 %.fca.2.extract.i.8 = extractvalue { i1, i64, i1 } %229, 2 br label %__hugr__.array.__read_bool.3.271.exit.8 cond_300_case_1.i.8: ; preds = %__hugr__.array.__read_bool.3.271.exit.7 - %read_bool.i.8 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.8) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.8) + %read_bool.i.8 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.8) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.8) br label %__hugr__.array.__read_bool.3.271.exit.8 __hugr__.array.__read_bool.3.271.exit.8: ; preds = %cond_300_case_1.i.8, %cond_300_case_0.i.8 @@ -714,17 +714,17 @@ __hugr__.array.__read_bool.3.271.exit.8: ; preds = %cond_300_case_1.i.8 %232 = getelementptr inbounds i8, i8* %84, i64 216 %233 = bitcast i8* %232 to { i1, i64, i1 }* %234 = load { i1, i64, i1 }, { i1, i64, i1 }* %233, align 4 - %.fca.0.extract.i899.9 = extractvalue { i1, i64, i1 } %234, 0 - %.fca.1.extract.i900.9 = extractvalue { i1, i64, i1 } %234, 1 - br i1 %.fca.0.extract.i899.9, label %cond_300_case_1.i.9, label %cond_300_case_0.i.9 + %.fca.0.extract.i893.9 = extractvalue { i1, i64, i1 } %234, 0 + %.fca.1.extract.i894.9 = extractvalue { i1, i64, i1 } %234, 1 + br i1 %.fca.0.extract.i893.9, label %cond_300_case_1.i.9, label %cond_300_case_0.i.9 cond_300_case_0.i.9: ; preds = %__hugr__.array.__read_bool.3.271.exit.8 %.fca.2.extract.i.9 = extractvalue { i1, i64, i1 } %234, 2 br label %__hugr__.array.__read_bool.3.271.exit.9 cond_300_case_1.i.9: ; preds = %__hugr__.array.__read_bool.3.271.exit.8 - %read_bool.i.9 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.9) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.9) + %read_bool.i.9 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.9) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.9) br label %__hugr__.array.__read_bool.3.271.exit.9 __hugr__.array.__read_bool.3.271.exit.9: ; preds = %cond_300_case_1.i.9, %cond_300_case_0.i.9 @@ -738,9 +738,9 @@ __hugr__.array.__read_bool.3.271.exit.9: ; preds = %cond_300_case_1.i.9 %238 = and i64 %237, 1023 store i64 %238, i64* %189, align 4 %239 = icmp eq i64 %238, 0 - br i1 %239, label %__barray_check_none_borrowed.exit905, label %mask_block_err.i904 + br i1 %239, label %__barray_check_none_borrowed.exit899, label %mask_block_err.i898 -__barray_check_none_borrowed.exit905: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 +__barray_check_none_borrowed.exit899: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 %out_arr_alloca = alloca <{ i32, i32, i1*, i1* }>, align 8 %x_ptr = getelementptr inbounds <{ i32, i32, i1*, i1* }>, <{ i32, i32, i1*, i1* }>* %out_arr_alloca, i64 0, i32 0 %y_ptr = getelementptr inbounds <{ i32, i32, i1*, i1* }>, <{ i32, i32, i1*, i1* }>* %out_arr_alloca, i64 0, i32 1 @@ -756,52 +756,52 @@ __barray_check_none_borrowed.exit905: ; preds = %__hugr__.array.__re store i8* %187, i8** %242, align 8 store i1* %.sub, i1** %mask_ptr, align 8 call void @print_bool_arr(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @res_cs.46C3C4B5.0, i64 0, i64 0), i64 15, <{ i32, i32, i1*, i1* }>* nonnull %out_arr_alloca) - br label %__barray_check_bounds.exit913 + br label %__barray_check_bounds.exit907 -mask_block_err.i904: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 +mask_block_err.i898: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit913: ; preds = %cond_exit_95.1, %__barray_check_none_borrowed.exit905 - %"90_0.sroa.0.0972" = phi i64 [ 0, %__barray_check_none_borrowed.exit905 ], [ %252, %cond_exit_95.1 ] - %243 = or i64 %"90_0.sroa.0.0972", 1 - %244 = lshr i64 %"90_0.sroa.0.0972", 6 +__barray_check_bounds.exit907: ; preds = %cond_exit_95.1, %__barray_check_none_borrowed.exit899 + %"90_0.sroa.0.0966" = phi i64 [ 0, %__barray_check_none_borrowed.exit899 ], [ %252, %cond_exit_95.1 ] + %243 = or i64 %"90_0.sroa.0.0966", 1 + %244 = lshr i64 %"90_0.sroa.0.0966", 6 %245 = getelementptr inbounds i64, i64* %7, i64 %244 %246 = load i64, i64* %245, align 4 - %247 = and i64 %"90_0.sroa.0.0972", 62 + %247 = and i64 %"90_0.sroa.0.0966", 62 %248 = shl nuw i64 1, %247 %249 = and i64 %246, %248 - %.not.i914 = icmp eq i64 %249, 0 - br i1 %.not.i914, label %panic.i915, label %cond_exit_95 + %.not.i908 = icmp eq i64 %249, 0 + br i1 %.not.i908, label %panic.i909, label %cond_exit_95 -panic.i915: ; preds = %cond_exit_95, %__barray_check_bounds.exit913 +panic.i909: ; preds = %cond_exit_95, %__barray_check_bounds.exit907 call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -cond_exit_95: ; preds = %__barray_check_bounds.exit913 +cond_exit_95: ; preds = %__barray_check_bounds.exit907 %250 = xor i64 %246, %248 store i64 %250, i64* %245, align 4 - %251 = getelementptr inbounds i64, i64* %5, i64 %"90_0.sroa.0.0972" - store i64 %"90_0.sroa.0.0972", i64* %251, align 4 - %252 = add nuw nsw i64 %"90_0.sroa.0.0972", 2 - %253 = lshr i64 %"90_0.sroa.0.0972", 6 + %251 = getelementptr inbounds i64, i64* %5, i64 %"90_0.sroa.0.0966" + store i64 %"90_0.sroa.0.0966", i64* %251, align 4 + %252 = add nuw nsw i64 %"90_0.sroa.0.0966", 2 + %253 = lshr i64 %"90_0.sroa.0.0966", 6 %254 = getelementptr inbounds i64, i64* %7, i64 %253 %255 = load i64, i64* %254, align 4 %256 = and i64 %243, 63 %257 = shl nuw i64 1, %256 %258 = and i64 %255, %257 - %.not.i914.1 = icmp eq i64 %258, 0 - br i1 %.not.i914.1, label %panic.i915, label %cond_exit_95.1 + %.not.i908.1 = icmp eq i64 %258, 0 + br i1 %.not.i908.1, label %panic.i909, label %cond_exit_95.1 cond_exit_95.1: ; preds = %cond_exit_95 %259 = xor i64 %255, %257 store i64 %259, i64* %254, align 4 %260 = getelementptr inbounds i64, i64* %5, i64 %243 store i64 %243, i64* %260, align 4 - %exitcond983.not.1 = icmp eq i64 %252, 100 - br i1 %exitcond983.not.1, label %loop_out212, label %__barray_check_bounds.exit913 + %exitcond977.not.1 = icmp eq i64 %252, 100 + br i1 %exitcond977.not.1, label %loop_out208, label %__barray_check_bounds.exit907 -loop_out212: ; preds = %cond_exit_95.1 +loop_out208: ; preds = %cond_exit_95.1 %261 = getelementptr inbounds i8, i8* %6, i64 8 %262 = bitcast i8* %261 to i64* %263 = load i64, i64* %262, align 4 @@ -811,9 +811,9 @@ loop_out212: ; preds = %cond_exit_95.1 %266 = icmp eq i64 %265, 0 %267 = icmp eq i64 %264, 0 %or.cond = select i1 %266, i1 %267, i1 false - br i1 %or.cond, label %__barray_check_none_borrowed.exit921, label %mask_block_err.i920 + br i1 %or.cond, label %__barray_check_none_borrowed.exit915, label %mask_block_err.i914 -__barray_check_none_borrowed.exit921: ; preds = %loop_out212 +__barray_check_none_borrowed.exit915: ; preds = %loop_out208 %268 = call i8* @heap_alloc(i64 800) %269 = bitcast i8* %268 to i64* %270 = call i8* @heap_alloc(i64 16) @@ -827,62 +827,62 @@ __barray_check_none_borrowed.exit921: ; preds = %loop_out212 %274 = load i64, i64* %7, align 4 %275 = icmp eq i64 %274, 0 %276 = icmp eq i64 %273, 0 - %or.cond986 = select i1 %275, i1 %276, i1 false - br i1 %or.cond986, label %__barray_check_none_borrowed.exit926, label %mask_block_err.i925 + %or.cond980 = select i1 %275, i1 %276, i1 false + br i1 %or.cond980, label %__barray_check_none_borrowed.exit920, label %mask_block_err.i919 -mask_block_err.i920: ; preds = %loop_out212 +mask_block_err.i914: ; preds = %loop_out208 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_none_borrowed.exit926: ; preds = %__barray_check_none_borrowed.exit921 - %out_arr_alloca287 = alloca <{ i32, i32, i64*, i1* }>, align 8 - %x_ptr288 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 0 - %y_ptr289 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 1 - %arr_ptr290 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 2 - %mask_ptr291 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 3 +__barray_check_none_borrowed.exit920: ; preds = %__barray_check_none_borrowed.exit915 + %out_arr_alloca282 = alloca <{ i32, i32, i64*, i1* }>, align 8 + %x_ptr283 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 0 + %y_ptr284 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 1 + %arr_ptr285 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 2 + %mask_ptr286 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 3 %277 = alloca [100 x i1], align 1 - %.sub635 = getelementptr inbounds [100 x i1], [100 x i1]* %277, i64 0, i64 0 + %.sub629 = getelementptr inbounds [100 x i1], [100 x i1]* %277, i64 0, i64 0 %278 = bitcast [100 x i1]* %277 to i8* call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(100) %278, i8 0, i64 100, i1 false) - store i32 100, i32* %x_ptr288, align 8 - store i32 1, i32* %y_ptr289, align 4 - %279 = bitcast i64** %arr_ptr290 to i8** + store i32 100, i32* %x_ptr283, align 8 + store i32 1, i32* %y_ptr284, align 4 + %279 = bitcast i64** %arr_ptr285 to i8** store i8* %4, i8** %279, align 8 - store i1* %.sub635, i1** %mask_ptr291, align 8 - call void @print_int_arr(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @res_is.F21393DB.0, i64 0, i64 0), i64 14, <{ i32, i32, i64*, i1* }>* nonnull %out_arr_alloca287) - br label %__barray_check_bounds.exit934 + store i1* %.sub629, i1** %mask_ptr286, align 8 + call void @print_int_arr(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @res_is.F21393DB.0, i64 0, i64 0), i64 14, <{ i32, i32, i64*, i1* }>* nonnull %out_arr_alloca282) + br label %__barray_check_bounds.exit928 -mask_block_err.i925: ; preds = %__barray_check_none_borrowed.exit921 +mask_block_err.i919: ; preds = %__barray_check_none_borrowed.exit915 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit934: ; preds = %cond_exit_130, %__barray_check_none_borrowed.exit926 - %"125_0.sroa.0.0974" = phi i64 [ 0, %__barray_check_none_borrowed.exit926 ], [ %280, %cond_exit_130 ] - %280 = add nuw nsw i64 %"125_0.sroa.0.0974", 1 - %281 = lshr i64 %"125_0.sroa.0.0974", 6 +__barray_check_bounds.exit928: ; preds = %cond_exit_130, %__barray_check_none_borrowed.exit920 + %"125_0.sroa.0.0968" = phi i64 [ 0, %__barray_check_none_borrowed.exit920 ], [ %280, %cond_exit_130 ] + %280 = add nuw nsw i64 %"125_0.sroa.0.0968", 1 + %281 = lshr i64 %"125_0.sroa.0.0968", 6 %282 = getelementptr inbounds i64, i64* %3, i64 %281 %283 = load i64, i64* %282, align 4 - %284 = and i64 %"125_0.sroa.0.0974", 63 + %284 = and i64 %"125_0.sroa.0.0968", 63 %285 = shl nuw i64 1, %284 %286 = and i64 %283, %285 - %.not.i935 = icmp eq i64 %286, 0 - br i1 %.not.i935, label %panic.i936, label %cond_exit_130 + %.not.i929 = icmp eq i64 %286, 0 + br i1 %.not.i929, label %panic.i930, label %cond_exit_130 -panic.i936: ; preds = %__barray_check_bounds.exit934 +panic.i930: ; preds = %__barray_check_bounds.exit928 call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -cond_exit_130: ; preds = %__barray_check_bounds.exit934 - %287 = sitofp i64 %"125_0.sroa.0.0974" to double +cond_exit_130: ; preds = %__barray_check_bounds.exit928 + %287 = sitofp i64 %"125_0.sroa.0.0968" to double %288 = fmul double %287, 6.250000e-02 %289 = xor i64 %283, %285 store i64 %289, i64* %282, align 4 - %290 = getelementptr inbounds double, double* %1, i64 %"125_0.sroa.0.0974" + %290 = getelementptr inbounds double, double* %1, i64 %"125_0.sroa.0.0968" store double %288, double* %290, align 8 - %exitcond984.not = icmp eq i64 %280, 100 - br i1 %exitcond984.not, label %loop_out299, label %__barray_check_bounds.exit934 + %exitcond978.not = icmp eq i64 %280, 100 + br i1 %exitcond978.not, label %loop_out294, label %__barray_check_bounds.exit928 -loop_out299: ; preds = %cond_exit_130 +loop_out294: ; preds = %cond_exit_130 %291 = getelementptr inbounds i8, i8* %2, i64 8 %292 = bitcast i8* %291 to i64* %293 = load i64, i64* %292, align 4 @@ -891,10 +891,10 @@ loop_out299: ; preds = %cond_exit_130 %295 = load i64, i64* %3, align 4 %296 = icmp eq i64 %295, 0 %297 = icmp eq i64 %294, 0 - %or.cond987 = select i1 %296, i1 %297, i1 false - br i1 %or.cond987, label %__barray_check_none_borrowed.exit942, label %mask_block_err.i941 + %or.cond981 = select i1 %296, i1 %297, i1 false + br i1 %or.cond981, label %__barray_check_none_borrowed.exit936, label %mask_block_err.i935 -__barray_check_none_borrowed.exit942: ; preds = %loop_out299 +__barray_check_none_borrowed.exit936: ; preds = %loop_out294 %298 = call i8* @heap_alloc(i64 800) %299 = bitcast i8* %298 to double* %300 = call i8* @heap_alloc(i64 16) @@ -908,32 +908,32 @@ __barray_check_none_borrowed.exit942: ; preds = %loop_out299 %304 = load i64, i64* %3, align 4 %305 = icmp eq i64 %304, 0 %306 = icmp eq i64 %303, 0 - %or.cond988 = select i1 %305, i1 %306, i1 false - br i1 %or.cond988, label %__barray_check_none_borrowed.exit947, label %mask_block_err.i946 + %or.cond982 = select i1 %305, i1 %306, i1 false + br i1 %or.cond982, label %__barray_check_none_borrowed.exit941, label %mask_block_err.i940 -mask_block_err.i941: ; preds = %loop_out299 +mask_block_err.i935: ; preds = %loop_out294 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_none_borrowed.exit947: ; preds = %__barray_check_none_borrowed.exit942 - %out_arr_alloca377 = alloca <{ i32, i32, double*, i1* }>, align 8 - %x_ptr378 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 0 - %y_ptr379 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 1 - %arr_ptr380 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 2 - %mask_ptr381 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 3 +__barray_check_none_borrowed.exit941: ; preds = %__barray_check_none_borrowed.exit936 + %out_arr_alloca371 = alloca <{ i32, i32, double*, i1* }>, align 8 + %x_ptr372 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 0 + %y_ptr373 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 1 + %arr_ptr374 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 2 + %mask_ptr375 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 3 %307 = alloca [100 x i1], align 1 - %.sub736 = getelementptr inbounds [100 x i1], [100 x i1]* %307, i64 0, i64 0 + %.sub730 = getelementptr inbounds [100 x i1], [100 x i1]* %307, i64 0, i64 0 %308 = bitcast [100 x i1]* %307 to i8* call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(100) %308, i8 0, i64 100, i1 false) - store i32 100, i32* %x_ptr378, align 8 - store i32 1, i32* %y_ptr379, align 4 - %309 = bitcast double** %arr_ptr380 to i8** + store i32 100, i32* %x_ptr372, align 8 + store i32 1, i32* %y_ptr373, align 4 + %309 = bitcast double** %arr_ptr374 to i8** store i8* %0, i8** %309, align 8 - store i1* %.sub736, i1** %mask_ptr381, align 8 - call void @print_float_arr(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @res_fs.CBD4AF54.0, i64 0, i64 0), i64 16, <{ i32, i32, double*, i1* }>* nonnull %out_arr_alloca377) + store i1* %.sub730, i1** %mask_ptr375, align 8 + call void @print_float_arr(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @res_fs.CBD4AF54.0, i64 0, i64 0), i64 16, <{ i32, i32, double*, i1* }>* nonnull %out_arr_alloca371) ret void -mask_block_err.i946: ; preds = %__barray_check_none_borrowed.exit942 +mask_block_err.i940: ; preds = %__barray_check_none_borrowed.exit936 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable } diff --git a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-unknown-linux-gnu-measure_qb_array/measure_qb_array_x86_64-unknown-linux-gnu b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-unknown-linux-gnu-measure_qb_array/measure_qb_array_x86_64-unknown-linux-gnu index ed180d102..757f214d3 100644 --- a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-unknown-linux-gnu-measure_qb_array/measure_qb_array_x86_64-unknown-linux-gnu +++ b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-unknown-linux-gnu-measure_qb_array/measure_qb_array_x86_64-unknown-linux-gnu @@ -38,8 +38,8 @@ entry: br label %cond_20_case_1.i cond_20_case_1.i: ; preds = %cond_exit_20.i, %entry - %"15_0.sroa.0.0295.i" = phi i64 [ 0, %entry ], [ %5, %cond_exit_20.i ] - %5 = add nuw nsw i64 %"15_0.sroa.0.0295.i", 1 + %"15_0.sroa.0.0294.i" = phi i64 [ 0, %entry ], [ %5, %cond_exit_20.i ] + %5 = add nuw nsw i64 %"15_0.sroa.0.0294.i", 1 %qalloc.i.i = tail call i64 @___qalloc() %not_max.not.i.i = icmp eq i64 %qalloc.i.i, -1 br i1 %not_max.not.i.i, label %id_bb.i.i, label %reset_bb.i.i @@ -59,10 +59,10 @@ cond_217_case_0.i.i: ; preds = %id_bb.i.i unreachable __barray_check_bounds.exit.i: ; preds = %id_bb.i.i - %8 = lshr i64 %"15_0.sroa.0.0295.i", 6 + %8 = lshr i64 %"15_0.sroa.0.0294.i", 6 %9 = getelementptr inbounds i64, i64* %4, i64 %8 %10 = load i64, i64* %9, align 4 - %11 = shl nuw nsw i64 1, %"15_0.sroa.0.0295.i" + %11 = shl nuw nsw i64 1, %"15_0.sroa.0.0294.i" %12 = and i64 %10, %11 %.not.i.i = icmp eq i64 %12, 0 br i1 %.not.i.i, label %panic.i.i, label %cond_exit_20.i @@ -75,7 +75,7 @@ cond_exit_20.i: ; preds = %__barray_check_boun %.fca.1.extract.i.i = extractvalue { i1, i64 } %7, 1 %13 = xor i64 %10, %11 store i64 %13, i64* %9, align 4 - %14 = getelementptr inbounds i64, i64* %2, i64 %"15_0.sroa.0.0295.i" + %14 = getelementptr inbounds i64, i64* %2, i64 %"15_0.sroa.0.0294.i" store i64 %.fca.1.extract.i.i, i64* %14, align 4 %exitcond.not.i = icmp eq i64 %5, 10 br i1 %exitcond.not.i, label %loop_out.i, label %cond_20_case_1.i @@ -83,10 +83,10 @@ cond_exit_20.i: ; preds = %__barray_check_boun loop_out.i: ; preds = %cond_exit_20.i %15 = load i64, i64* %4, align 4 %16 = and i64 %15, 1 - %.not.i259.i = icmp eq i64 %16, 0 - br i1 %.not.i259.i, label %__barray_mask_borrow.exit.i, label %panic.i260.i + %.not.i258.i = icmp eq i64 %16, 0 + br i1 %.not.i258.i, label %__barray_mask_borrow.exit.i, label %panic.i259.i -panic.i260.i: ; preds = %loop_out.i +panic.i259.i: ; preds = %loop_out.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable @@ -97,27 +97,27 @@ __barray_mask_borrow.exit.i: ; preds = %loop_out.i tail call void @___rxy(i64 %18, double 0x400921FB54442D18, double 0.000000e+00) %19 = load i64, i64* %4, align 4 %20 = and i64 %19, 1 - %.not.i261.i = icmp eq i64 %20, 0 - br i1 %.not.i261.i, label %panic.i262.i, label %__barray_mask_return.exit263.i + %.not.i260.i = icmp eq i64 %20, 0 + br i1 %.not.i260.i, label %panic.i261.i, label %__barray_mask_return.exit262.i -panic.i262.i: ; preds = %__barray_mask_borrow.exit.i +panic.i261.i: ; preds = %__barray_mask_borrow.exit.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit263.i: ; preds = %__barray_mask_borrow.exit.i +__barray_mask_return.exit262.i: ; preds = %__barray_mask_borrow.exit.i %21 = xor i64 %19, 1 store i64 %21, i64* %4, align 4 store i64 %18, i64* %2, align 4 %22 = load i64, i64* %4, align 4 %23 = and i64 %22, 4 - %.not.i264.i = icmp eq i64 %23, 0 - br i1 %.not.i264.i, label %__barray_mask_borrow.exit266.i, label %panic.i265.i + %.not.i263.i = icmp eq i64 %23, 0 + br i1 %.not.i263.i, label %__barray_mask_borrow.exit265.i, label %panic.i264.i -panic.i265.i: ; preds = %__barray_mask_return.exit263.i +panic.i264.i: ; preds = %__barray_mask_return.exit262.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit266.i: ; preds = %__barray_mask_return.exit263.i +__barray_mask_borrow.exit265.i: ; preds = %__barray_mask_return.exit262.i %24 = xor i64 %22, 4 store i64 %24, i64* %4, align 4 %25 = getelementptr inbounds i8, i8* %1, i64 16 @@ -126,27 +126,27 @@ __barray_mask_borrow.exit266.i: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %27, double 0x400921FB54442D18, double 0.000000e+00) %28 = load i64, i64* %4, align 4 %29 = and i64 %28, 4 - %.not.i267.i = icmp eq i64 %29, 0 - br i1 %.not.i267.i, label %panic.i268.i, label %__barray_mask_return.exit269.i + %.not.i266.i = icmp eq i64 %29, 0 + br i1 %.not.i266.i, label %panic.i267.i, label %__barray_mask_return.exit268.i -panic.i268.i: ; preds = %__barray_mask_borrow.exit266.i +panic.i267.i: ; preds = %__barray_mask_borrow.exit265.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit269.i: ; preds = %__barray_mask_borrow.exit266.i +__barray_mask_return.exit268.i: ; preds = %__barray_mask_borrow.exit265.i %30 = xor i64 %28, 4 store i64 %30, i64* %4, align 4 store i64 %27, i64* %26, align 4 %31 = load i64, i64* %4, align 4 %32 = and i64 %31, 8 - %.not.i270.i = icmp eq i64 %32, 0 - br i1 %.not.i270.i, label %__barray_mask_borrow.exit272.i, label %panic.i271.i + %.not.i269.i = icmp eq i64 %32, 0 + br i1 %.not.i269.i, label %__barray_mask_borrow.exit271.i, label %panic.i270.i -panic.i271.i: ; preds = %__barray_mask_return.exit269.i +panic.i270.i: ; preds = %__barray_mask_return.exit268.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit272.i: ; preds = %__barray_mask_return.exit269.i +__barray_mask_borrow.exit271.i: ; preds = %__barray_mask_return.exit268.i %33 = xor i64 %31, 8 store i64 %33, i64* %4, align 4 %34 = getelementptr inbounds i8, i8* %1, i64 24 @@ -155,27 +155,27 @@ __barray_mask_borrow.exit272.i: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %36, double 0x400921FB54442D18, double 0.000000e+00) %37 = load i64, i64* %4, align 4 %38 = and i64 %37, 8 - %.not.i273.i = icmp eq i64 %38, 0 - br i1 %.not.i273.i, label %panic.i274.i, label %__barray_mask_return.exit275.i + %.not.i272.i = icmp eq i64 %38, 0 + br i1 %.not.i272.i, label %panic.i273.i, label %__barray_mask_return.exit274.i -panic.i274.i: ; preds = %__barray_mask_borrow.exit272.i +panic.i273.i: ; preds = %__barray_mask_borrow.exit271.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit275.i: ; preds = %__barray_mask_borrow.exit272.i +__barray_mask_return.exit274.i: ; preds = %__barray_mask_borrow.exit271.i %39 = xor i64 %37, 8 store i64 %39, i64* %4, align 4 store i64 %36, i64* %35, align 4 %40 = load i64, i64* %4, align 4 %41 = and i64 %40, 512 - %.not.i276.i = icmp eq i64 %41, 0 - br i1 %.not.i276.i, label %__barray_mask_borrow.exit278.i, label %panic.i277.i + %.not.i275.i = icmp eq i64 %41, 0 + br i1 %.not.i275.i, label %__barray_mask_borrow.exit277.i, label %panic.i276.i -panic.i277.i: ; preds = %__barray_mask_return.exit275.i +panic.i276.i: ; preds = %__barray_mask_return.exit274.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit278.i: ; preds = %__barray_mask_return.exit275.i +__barray_mask_borrow.exit277.i: ; preds = %__barray_mask_return.exit274.i %42 = xor i64 %40, 512 store i64 %42, i64* %4, align 4 %43 = getelementptr inbounds i8, i8* %1, i64 72 @@ -184,14 +184,14 @@ __barray_mask_borrow.exit278.i: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %45, double 0x400921FB54442D18, double 0.000000e+00) %46 = load i64, i64* %4, align 4 %47 = and i64 %46, 512 - %.not.i279.i = icmp eq i64 %47, 0 - br i1 %.not.i279.i, label %panic.i280.i, label %__barray_mask_return.exit281.i + %.not.i278.i = icmp eq i64 %47, 0 + br i1 %.not.i278.i, label %panic.i279.i, label %__barray_mask_return.exit280.i -panic.i280.i: ; preds = %__barray_mask_borrow.exit278.i +panic.i279.i: ; preds = %__barray_mask_borrow.exit277.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit281.i: ; preds = %__barray_mask_borrow.exit278.i +__barray_mask_return.exit280.i: ; preds = %__barray_mask_borrow.exit277.i %48 = xor i64 %46, 512 store i64 %48, i64* %4, align 4 store i64 %45, i64* %44, align 4 @@ -212,19 +212,19 @@ mask_block_ok.i.i.i.i: ; preds = %cond_exit_353.i.i "__hugr__.$measure_array$$n(10).277.exit.i": ; preds = %mask_block_ok.i.i.i.i tail call void @heap_free(i8* nonnull %1) tail call void @heap_free(i8* nonnull %3) - br label %__barray_check_bounds.exit284.i + br label %__barray_check_bounds.exit283.i mask_block_err.i.i.i.i: ; preds = %mask_block_ok.i.i.i.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -56: ; preds = %cond_exit_353.i.i, %__barray_mask_return.exit281.i - %"303_0.sroa.15.0.i297.i" = phi i64 [ 0, %__barray_mask_return.exit281.i ], [ %57, %cond_exit_353.i.i ] - %57 = add nuw nsw i64 %"303_0.sroa.15.0.i297.i", 1 - %58 = lshr i64 %"303_0.sroa.15.0.i297.i", 6 +56: ; preds = %cond_exit_353.i.i, %__barray_mask_return.exit280.i + %"303_0.sroa.15.0.i296.i" = phi i64 [ 0, %__barray_mask_return.exit280.i ], [ %57, %cond_exit_353.i.i ] + %57 = add nuw nsw i64 %"303_0.sroa.15.0.i296.i", 1 + %58 = lshr i64 %"303_0.sroa.15.0.i296.i", 6 %59 = getelementptr inbounds i64, i64* %4, i64 %58 %60 = load i64, i64* %59, align 4 - %61 = shl nuw nsw i64 1, %"303_0.sroa.15.0.i297.i" + %61 = shl nuw nsw i64 1, %"303_0.sroa.15.0.i296.i" %62 = and i64 %60, %61 %.not.i99.i.i.i = icmp eq i64 %62, 0 br i1 %.not.i99.i.i.i, label %__barray_check_bounds.exit.i.i, label %panic.i.i.i.i @@ -236,7 +236,7 @@ panic.i.i.i.i: ; preds = %56 __barray_check_bounds.exit.i.i: ; preds = %56 %63 = xor i64 %60, %61 store i64 %63, i64* %59, align 4 - %64 = getelementptr inbounds i64, i64* %2, i64 %"303_0.sroa.15.0.i297.i" + %64 = getelementptr inbounds i64, i64* %2, i64 %"303_0.sroa.15.0.i296.i" %65 = load i64, i64* %64, align 4 %lazy_measure.i.i = tail call i64 @___lazy_measure(i64 %65) tail call void @___qfree(i64 %65) @@ -254,51 +254,51 @@ cond_exit_353.i.i: ; preds = %__barray_check_boun %"367_054.fca.1.insert.i.i" = insertvalue { i1, i64, i1 } { i1 true, i64 poison, i1 poison }, i64 %lazy_measure.i.i, 1 %69 = xor i64 %67, %61 store i64 %69, i64* %66, align 4 - %70 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"303_0.sroa.15.0.i297.i" + %70 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"303_0.sroa.15.0.i296.i" store { i1, i64, i1 } %"367_054.fca.1.insert.i.i", { i1, i64, i1 }* %70, align 4 - %exitcond298.not.i = icmp eq i64 %57, 10 - br i1 %exitcond298.not.i, label %mask_block_ok.i.i.i.i, label %56 + %exitcond297.not.i = icmp eq i64 %57, 10 + br i1 %exitcond297.not.i, label %mask_block_ok.i.i.i.i, label %56 -cond_160_case_0.i: ; preds = %cond_exit_160.i +cond_187_case_0.i: ; preds = %cond_exit_187.i %71 = load i64, i64* %52, align 4 %72 = or i64 %71, -1024 store i64 %72, i64* %52, align 4 %73 = icmp eq i64 %72, -1 br i1 %73, label %__hugr__.main.1.exit, label %mask_block_err.i.i -mask_block_err.i.i: ; preds = %cond_160_case_0.i +mask_block_err.i.i: ; preds = %cond_187_case_0.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit284.i: ; preds = %"__hugr__.$measure_array$$n(10).277.exit.i", %cond_exit_160.i - %"162_0.0.i1" = phi i64 [ 0, %"__hugr__.$measure_array$$n(10).277.exit.i" ], [ %82, %cond_exit_160.i ] - %74 = lshr i64 %"162_0.0.i1", 6 +__barray_check_bounds.exit283.i: ; preds = %"__hugr__.$measure_array$$n(10).277.exit.i", %cond_exit_187.i + %"164_0.0.i1" = phi i64 [ 0, %"__hugr__.$measure_array$$n(10).277.exit.i" ], [ %82, %cond_exit_187.i ] + %74 = lshr i64 %"164_0.0.i1", 6 %75 = getelementptr inbounds i64, i64* %52, i64 %74 %76 = load i64, i64* %75, align 4 - %77 = shl nuw nsw i64 1, %"162_0.0.i1" + %77 = shl nuw nsw i64 1, %"164_0.0.i1" %78 = and i64 %76, %77 %.not.i = icmp eq i64 %78, 0 - br i1 %.not.i, label %__barray_mask_borrow.exit289.i, label %cond_exit_160.i + br i1 %.not.i, label %__barray_mask_borrow.exit288.i, label %cond_exit_187.i -__barray_mask_borrow.exit289.i: ; preds = %__barray_check_bounds.exit284.i +__barray_mask_borrow.exit288.i: ; preds = %__barray_check_bounds.exit283.i %79 = xor i64 %76, %77 store i64 %79, i64* %75, align 4 - %80 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"162_0.0.i1" + %80 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"164_0.0.i1" %81 = load { i1, i64, i1 }, { i1, i64, i1 }* %80, align 4 - %.fca.0.extract180.i = extractvalue { i1, i64, i1 } %81, 0 - br i1 %.fca.0.extract180.i, label %cond_85_case_1.i, label %cond_exit_160.i + %.fca.0.extract179.i = extractvalue { i1, i64, i1 } %81, 0 + br i1 %.fca.0.extract179.i, label %cond_87_case_1.i, label %cond_exit_187.i -cond_exit_160.i: ; preds = %cond_85_case_1.i, %__barray_mask_borrow.exit289.i, %__barray_check_bounds.exit284.i - %82 = add nuw nsw i64 %"162_0.0.i1", 1 +cond_exit_187.i: ; preds = %cond_87_case_1.i, %__barray_mask_borrow.exit288.i, %__barray_check_bounds.exit283.i + %82 = add nuw nsw i64 %"164_0.0.i1", 1 %exitcond.not = icmp eq i64 %82, 10 - br i1 %exitcond.not, label %cond_160_case_0.i, label %__barray_check_bounds.exit284.i + br i1 %exitcond.not, label %cond_187_case_0.i, label %__barray_check_bounds.exit283.i -cond_85_case_1.i: ; preds = %__barray_mask_borrow.exit289.i +cond_87_case_1.i: ; preds = %__barray_mask_borrow.exit288.i %.fca.1.extract.i = extractvalue { i1, i64, i1 } %81, 1 tail call void @___dec_future_refcount(i64 %.fca.1.extract.i) - br label %cond_exit_160.i + br label %cond_exit_187.i -__hugr__.main.1.exit: ; preds = %cond_160_case_0.i +__hugr__.main.1.exit: ; preds = %cond_187_case_0.i tail call void @heap_free(i8* %49) tail call void @heap_free(i8* nonnull %51) %83 = tail call i64 @teardown() diff --git a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-unknown-linux-gnu-print_array/print_array_x86_64-unknown-linux-gnu b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-unknown-linux-gnu-print_array/print_array_x86_64-unknown-linux-gnu index ea2f0aff9..2277df0a1 100644 --- a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-unknown-linux-gnu-print_array/print_array_x86_64-unknown-linux-gnu +++ b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-unknown-linux-gnu-print_array/print_array_x86_64-unknown-linux-gnu @@ -34,8 +34,8 @@ alloca_block: br label %cond_20_case_1 cond_20_case_1: ; preds = %alloca_block, %cond_exit_20 - %"15_0.sroa.0.0961" = phi i64 [ 0, %alloca_block ], [ %12, %cond_exit_20 ] - %12 = add nuw nsw i64 %"15_0.sroa.0.0961", 1 + %"15_0.sroa.0.0955" = phi i64 [ 0, %alloca_block ], [ %12, %cond_exit_20 ] + %12 = add nuw nsw i64 %"15_0.sroa.0.0955", 1 %qalloc.i = tail call i64 @___qalloc() %not_max.not.i = icmp eq i64 %qalloc.i, -1 br i1 %not_max.not.i, label %id_bb.i, label %reset_bb.i @@ -55,10 +55,10 @@ cond_303_case_0.i: ; preds = %id_bb.i unreachable __barray_check_bounds.exit: ; preds = %id_bb.i - %15 = lshr i64 %"15_0.sroa.0.0961", 6 + %15 = lshr i64 %"15_0.sroa.0.0955", 6 %16 = getelementptr inbounds i64, i64* %11, i64 %15 %17 = load i64, i64* %16, align 4 - %18 = shl nuw nsw i64 1, %"15_0.sroa.0.0961" + %18 = shl nuw nsw i64 1, %"15_0.sroa.0.0955" %19 = and i64 %17, %18 %.not.i = icmp eq i64 %19, 0 br i1 %.not.i, label %panic.i, label %cond_exit_20 @@ -71,7 +71,7 @@ cond_exit_20: ; preds = %__barray_check_boun %.fca.1.extract.i = extractvalue { i1, i64 } %14, 1 %20 = xor i64 %17, %18 store i64 %20, i64* %16, align 4 - %21 = getelementptr inbounds i64, i64* %9, i64 %"15_0.sroa.0.0961" + %21 = getelementptr inbounds i64, i64* %9, i64 %"15_0.sroa.0.0955" store i64 %.fca.1.extract.i, i64* %21, align 4 %exitcond.not = icmp eq i64 %12, 10 br i1 %exitcond.not, label %loop_out, label %cond_20_case_1 @@ -79,10 +79,10 @@ cond_exit_20: ; preds = %__barray_check_boun loop_out: ; preds = %cond_exit_20 %22 = load i64, i64* %11, align 4 %23 = and i64 %22, 1 - %.not.i852 = icmp eq i64 %23, 0 - br i1 %.not.i852, label %__barray_mask_borrow.exit, label %panic.i853 + %.not.i846 = icmp eq i64 %23, 0 + br i1 %.not.i846, label %__barray_mask_borrow.exit, label %panic.i847 -panic.i853: ; preds = %loop_out +panic.i847: ; preds = %loop_out tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable @@ -93,27 +93,27 @@ __barray_mask_borrow.exit: ; preds = %loop_out tail call void @___rxy(i64 %25, double 0x400921FB54442D18, double 0.000000e+00) %26 = load i64, i64* %11, align 4 %27 = and i64 %26, 1 - %.not.i854 = icmp eq i64 %27, 0 - br i1 %.not.i854, label %panic.i855, label %__barray_mask_return.exit856 + %.not.i848 = icmp eq i64 %27, 0 + br i1 %.not.i848, label %panic.i849, label %__barray_mask_return.exit850 -panic.i855: ; preds = %__barray_mask_borrow.exit +panic.i849: ; preds = %__barray_mask_borrow.exit tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit856: ; preds = %__barray_mask_borrow.exit +__barray_mask_return.exit850: ; preds = %__barray_mask_borrow.exit %28 = xor i64 %26, 1 store i64 %28, i64* %11, align 4 store i64 %25, i64* %9, align 4 %29 = load i64, i64* %11, align 4 %30 = and i64 %29, 4 - %.not.i857 = icmp eq i64 %30, 0 - br i1 %.not.i857, label %__barray_mask_borrow.exit859, label %panic.i858 + %.not.i851 = icmp eq i64 %30, 0 + br i1 %.not.i851, label %__barray_mask_borrow.exit853, label %panic.i852 -panic.i858: ; preds = %__barray_mask_return.exit856 +panic.i852: ; preds = %__barray_mask_return.exit850 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit859: ; preds = %__barray_mask_return.exit856 +__barray_mask_borrow.exit853: ; preds = %__barray_mask_return.exit850 %31 = xor i64 %29, 4 store i64 %31, i64* %11, align 4 %32 = getelementptr inbounds i8, i8* %8, i64 16 @@ -122,27 +122,27 @@ __barray_mask_borrow.exit859: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %34, double 0x400921FB54442D18, double 0.000000e+00) %35 = load i64, i64* %11, align 4 %36 = and i64 %35, 4 - %.not.i860 = icmp eq i64 %36, 0 - br i1 %.not.i860, label %panic.i861, label %__barray_mask_return.exit862 + %.not.i854 = icmp eq i64 %36, 0 + br i1 %.not.i854, label %panic.i855, label %__barray_mask_return.exit856 -panic.i861: ; preds = %__barray_mask_borrow.exit859 +panic.i855: ; preds = %__barray_mask_borrow.exit853 tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit862: ; preds = %__barray_mask_borrow.exit859 +__barray_mask_return.exit856: ; preds = %__barray_mask_borrow.exit853 %37 = xor i64 %35, 4 store i64 %37, i64* %11, align 4 store i64 %34, i64* %33, align 4 %38 = load i64, i64* %11, align 4 %39 = and i64 %38, 8 - %.not.i863 = icmp eq i64 %39, 0 - br i1 %.not.i863, label %__barray_mask_borrow.exit865, label %panic.i864 + %.not.i857 = icmp eq i64 %39, 0 + br i1 %.not.i857, label %__barray_mask_borrow.exit859, label %panic.i858 -panic.i864: ; preds = %__barray_mask_return.exit862 +panic.i858: ; preds = %__barray_mask_return.exit856 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit865: ; preds = %__barray_mask_return.exit862 +__barray_mask_borrow.exit859: ; preds = %__barray_mask_return.exit856 %40 = xor i64 %38, 8 store i64 %40, i64* %11, align 4 %41 = getelementptr inbounds i8, i8* %8, i64 24 @@ -151,27 +151,27 @@ __barray_mask_borrow.exit865: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %43, double 0x400921FB54442D18, double 0.000000e+00) %44 = load i64, i64* %11, align 4 %45 = and i64 %44, 8 - %.not.i866 = icmp eq i64 %45, 0 - br i1 %.not.i866, label %panic.i867, label %__barray_mask_return.exit868 + %.not.i860 = icmp eq i64 %45, 0 + br i1 %.not.i860, label %panic.i861, label %__barray_mask_return.exit862 -panic.i867: ; preds = %__barray_mask_borrow.exit865 +panic.i861: ; preds = %__barray_mask_borrow.exit859 tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit868: ; preds = %__barray_mask_borrow.exit865 +__barray_mask_return.exit862: ; preds = %__barray_mask_borrow.exit859 %46 = xor i64 %44, 8 store i64 %46, i64* %11, align 4 store i64 %43, i64* %42, align 4 %47 = load i64, i64* %11, align 4 %48 = and i64 %47, 512 - %.not.i869 = icmp eq i64 %48, 0 - br i1 %.not.i869, label %__barray_mask_borrow.exit871, label %panic.i870 + %.not.i863 = icmp eq i64 %48, 0 + br i1 %.not.i863, label %__barray_mask_borrow.exit865, label %panic.i864 -panic.i870: ; preds = %__barray_mask_return.exit868 +panic.i864: ; preds = %__barray_mask_return.exit862 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit871: ; preds = %__barray_mask_return.exit868 +__barray_mask_borrow.exit865: ; preds = %__barray_mask_return.exit862 %49 = xor i64 %47, 512 store i64 %49, i64* %11, align 4 %50 = getelementptr inbounds i8, i8* %8, i64 72 @@ -180,14 +180,14 @@ __barray_mask_borrow.exit871: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %52, double 0x400921FB54442D18, double 0.000000e+00) %53 = load i64, i64* %11, align 4 %54 = and i64 %53, 512 - %.not.i872 = icmp eq i64 %54, 0 - br i1 %.not.i872, label %panic.i873, label %__barray_mask_return.exit874 + %.not.i866 = icmp eq i64 %54, 0 + br i1 %.not.i866, label %panic.i867, label %__barray_mask_return.exit868 -panic.i873: ; preds = %__barray_mask_borrow.exit871 +panic.i867: ; preds = %__barray_mask_borrow.exit865 tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit874: ; preds = %__barray_mask_borrow.exit871 +__barray_mask_return.exit868: ; preds = %__barray_mask_borrow.exit865 %55 = xor i64 %53, 512 store i64 %55, i64* %11, align 4 store i64 %52, i64* %51, align 4 @@ -223,13 +223,13 @@ mask_block_err.i.i.i: ; preds = %mask_block_ok.i.i.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -69: ; preds = %__barray_mask_return.exit874, %cond_exit_443.i - %"393_0.sroa.15.0.i963" = phi i64 [ 0, %__barray_mask_return.exit874 ], [ %70, %cond_exit_443.i ] - %70 = add nuw nsw i64 %"393_0.sroa.15.0.i963", 1 - %71 = lshr i64 %"393_0.sroa.15.0.i963", 6 +69: ; preds = %__barray_mask_return.exit868, %cond_exit_443.i + %"393_0.sroa.15.0.i957" = phi i64 [ 0, %__barray_mask_return.exit868 ], [ %70, %cond_exit_443.i ] + %70 = add nuw nsw i64 %"393_0.sroa.15.0.i957", 1 + %71 = lshr i64 %"393_0.sroa.15.0.i957", 6 %72 = getelementptr inbounds i64, i64* %11, i64 %71 %73 = load i64, i64* %72, align 4 - %74 = shl nuw nsw i64 1, %"393_0.sroa.15.0.i963" + %74 = shl nuw nsw i64 1, %"393_0.sroa.15.0.i957" %75 = and i64 %73, %74 %.not.i99.i.i = icmp eq i64 %75, 0 br i1 %.not.i99.i.i, label %__barray_check_bounds.exit.i, label %panic.i.i.i @@ -241,7 +241,7 @@ panic.i.i.i: ; preds = %69 __barray_check_bounds.exit.i: ; preds = %69 %76 = xor i64 %73, %74 store i64 %76, i64* %72, align 4 - %77 = getelementptr inbounds i64, i64* %9, i64 %"393_0.sroa.15.0.i963" + %77 = getelementptr inbounds i64, i64* %9, i64 %"393_0.sroa.15.0.i957" %78 = load i64, i64* %77, align 4 %lazy_measure.i = tail call i64 @___lazy_measure(i64 %78) tail call void @___qfree(i64 %78) @@ -259,10 +259,10 @@ cond_exit_443.i: ; preds = %__barray_check_boun %"457_054.fca.1.insert.i" = insertvalue { i1, i64, i1 } { i1 true, i64 poison, i1 poison }, i64 %lazy_measure.i, 1 %82 = xor i64 %80, %74 store i64 %82, i64* %79, align 4 - %83 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %"393_0.sroa.15.0.i963" + %83 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %"393_0.sroa.15.0.i957" store { i1, i64, i1 } %"457_054.fca.1.insert.i", { i1, i64, i1 }* %83, align 4 - %exitcond979.not = icmp eq i64 %70, 10 - br i1 %exitcond979.not, label %mask_block_ok.i.i.i, label %69 + %exitcond973.not = icmp eq i64 %70, 10 + br i1 %exitcond973.not, label %mask_block_ok.i.i.i, label %69 __barray_check_none_borrowed.exit: ; preds = %"__hugr__.$measure_array$$n(10).367.exit" %84 = tail call i8* @heap_alloc(i64 240) @@ -277,78 +277,78 @@ mask_block_err.i: ; preds = %"__hugr__.$measure_ tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -89: ; preds = %__barray_check_none_borrowed.exit, %__hugr__.const_fun_290.309.exit - %storemerge850968 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %107, %__hugr__.const_fun_290.309.exit ] - %90 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %105, %__hugr__.const_fun_290.309.exit ] - %91 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %storemerge850968 +89: ; preds = %__barray_check_none_borrowed.exit, %__hugr__.const_fun_338.322.exit + %storemerge844962 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %107, %__hugr__.const_fun_338.322.exit ] + %90 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %105, %__hugr__.const_fun_338.322.exit ] + %91 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %storemerge844962 %92 = load { i1, i64, i1 }, { i1, i64, i1 }* %91, align 4 %.fca.0.extract118.i = extractvalue { i1, i64, i1 } %92, 0 %.fca.1.extract119.i = extractvalue { i1, i64, i1 } %92, 1 - br i1 %.fca.0.extract118.i, label %cond_525_case_1.i, label %cond_exit_525.i + br i1 %.fca.0.extract118.i, label %cond_513_case_1.i, label %cond_exit_513.i -cond_525_case_1.i: ; preds = %89 +cond_513_case_1.i: ; preds = %89 tail call void @___inc_future_refcount(i64 %.fca.1.extract119.i) %93 = insertvalue { i1, i64, i1 } { i1 true, i64 poison, i1 poison }, i64 %.fca.1.extract119.i, 1 - br label %cond_exit_525.i + br label %cond_exit_513.i -cond_exit_525.i: ; preds = %cond_525_case_1.i, %89 - %.pn.i = phi { i1, i64, i1 } [ %93, %cond_525_case_1.i ], [ %92, %89 ] +cond_exit_513.i: ; preds = %cond_513_case_1.i, %89 + %.pn.i = phi { i1, i64, i1 } [ %93, %cond_513_case_1.i ], [ %92, %89 ] %"04.sroa.6.0.i" = extractvalue { i1, i64, i1 } %.pn.i, 2 %94 = icmp ult i64 %90, 10 - br i1 %94, label %95, label %cond_528_case_0.i + br i1 %94, label %95, label %cond_516_case_0.i -95: ; preds = %cond_exit_525.i +95: ; preds = %cond_exit_513.i %96 = lshr i64 %90, 6 %97 = getelementptr inbounds i64, i64* %65, i64 %96 %98 = load i64, i64* %97, align 4 %99 = shl nuw nsw i64 1, %90 %100 = and i64 %98, %99 - %.not.i.i876 = icmp eq i64 %100, 0 - br i1 %.not.i.i876, label %cond_528_case_1.i, label %panic.i.i877 + %.not.i.i870 = icmp eq i64 %100, 0 + br i1 %.not.i.i870, label %cond_516_case_1.i, label %panic.i.i871 -panic.i.i877: ; preds = %95 +panic.i.i871: ; preds = %95 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -cond_528_case_0.i: ; preds = %cond_exit_525.i +cond_516_case_0.i: ; preds = %cond_exit_513.i tail call void @panic(i32 1001, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @"e_Expected v.E6312129.0", i64 0, i64 0)) unreachable -cond_528_case_1.i: ; preds = %95 +cond_516_case_1.i: ; preds = %95 %"17.fca.2.insert.i" = insertvalue { i1, i64, i1 } %92, i1 %"04.sroa.6.0.i", 2 %101 = insertvalue { i1, { i1, i64, i1 } } { i1 true, { i1, i64, i1 } poison }, { i1, i64, i1 } %"17.fca.2.insert.i", 1 %102 = getelementptr inbounds { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %88, i64 %90 %103 = getelementptr inbounds { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %102, i64 0, i32 0 %104 = load i1, i1* %103, align 1 store { i1, { i1, i64, i1 } } %101, { i1, { i1, i64, i1 } }* %102, align 4 - br i1 %104, label %cond_529_case_1.i, label %__hugr__.const_fun_290.309.exit + br i1 %104, label %cond_517_case_1.i, label %__hugr__.const_fun_338.322.exit -cond_529_case_1.i: ; preds = %cond_528_case_1.i +cond_517_case_1.i: ; preds = %cond_516_case_1.i tail call void @panic(i32 1001, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @"e_Expected v.2F17E0A9.0", i64 0, i64 0)) unreachable -__hugr__.const_fun_290.309.exit: ; preds = %cond_528_case_1.i +__hugr__.const_fun_338.322.exit: ; preds = %cond_516_case_1.i %105 = add nuw nsw i64 %90, 1 - %106 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %85, i64 %storemerge850968 + %106 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %85, i64 %storemerge844962 store { i1, i64, i1 } %"17.fca.2.insert.i", { i1, i64, i1 }* %106, align 4 - %107 = add nuw nsw i64 %storemerge850968, 1 - %exitcond980.not = icmp eq i64 %107, 10 - br i1 %exitcond980.not, label %mask_block_ok.i881, label %89 + %107 = add nuw nsw i64 %storemerge844962, 1 + %exitcond974.not = icmp eq i64 %107, 10 + br i1 %exitcond974.not, label %mask_block_ok.i875, label %89 -mask_block_ok.i881: ; preds = %__hugr__.const_fun_290.309.exit +mask_block_ok.i875: ; preds = %__hugr__.const_fun_338.322.exit tail call void @heap_free(i8* nonnull %56) tail call void @heap_free(i8* %58) %108 = load i64, i64* %65, align 4 %109 = and i64 %108, 1023 store i64 %109, i64* %65, align 4 %110 = icmp eq i64 %109, 0 - br i1 %110, label %__barray_check_none_borrowed.exit883, label %mask_block_err.i882 + br i1 %110, label %__barray_check_none_borrowed.exit877, label %mask_block_err.i876 -mask_block_err.i882: ; preds = %mask_block_ok.i881 +mask_block_err.i876: ; preds = %mask_block_ok.i875 tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_none_borrowed.exit883: ; preds = %mask_block_ok.i881 +__barray_check_none_borrowed.exit877: ; preds = %mask_block_ok.i875 %111 = tail call i8* @heap_alloc(i64 240) %112 = bitcast i8* %111 to { i1, i64, i1 }* %113 = tail call i8* @heap_alloc(i64 8) @@ -356,22 +356,22 @@ __barray_check_none_borrowed.exit883: ; preds = %mask_block_ok.i881 store i64 0, i64* %114, align 1 %115 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %88, align 4 %.fca.0.extract11.i = extractvalue { i1, { i1, i64, i1 } } %115, 0 - br i1 %.fca.0.extract11.i, label %__hugr__.const_fun_284.290.exit, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i, label %__hugr__.const_fun_287.338.exit, label %cond_558_case_0.i -cond_570_case_0.i: ; preds = %__hugr__.const_fun_284.290.exit.8, %__hugr__.const_fun_284.290.exit.7, %__hugr__.const_fun_284.290.exit.6, %__hugr__.const_fun_284.290.exit.5, %__hugr__.const_fun_284.290.exit.4, %__hugr__.const_fun_284.290.exit.3, %__hugr__.const_fun_284.290.exit.2, %__hugr__.const_fun_284.290.exit.1, %__hugr__.const_fun_284.290.exit, %__barray_check_none_borrowed.exit883 +cond_558_case_0.i: ; preds = %__hugr__.const_fun_287.338.exit.8, %__hugr__.const_fun_287.338.exit.7, %__hugr__.const_fun_287.338.exit.6, %__hugr__.const_fun_287.338.exit.5, %__hugr__.const_fun_287.338.exit.4, %__hugr__.const_fun_287.338.exit.3, %__hugr__.const_fun_287.338.exit.2, %__hugr__.const_fun_287.338.exit.1, %__hugr__.const_fun_287.338.exit, %__barray_check_none_borrowed.exit877 tail call void @panic(i32 1001, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @"e_Expected v.E6312129.0", i64 0, i64 0)) unreachable -__hugr__.const_fun_284.290.exit: ; preds = %__barray_check_none_borrowed.exit883 +__hugr__.const_fun_287.338.exit: ; preds = %__barray_check_none_borrowed.exit877 %116 = extractvalue { i1, { i1, i64, i1 } } %115, 1 store { i1, i64, i1 } %116, { i1, i64, i1 }* %112, align 4 %117 = getelementptr inbounds i8, i8* %63, i64 32 %118 = bitcast i8* %117 to { i1, { i1, i64, i1 } }* %119 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %118, align 4 %.fca.0.extract11.i.1 = extractvalue { i1, { i1, i64, i1 } } %119, 0 - br i1 %.fca.0.extract11.i.1, label %__hugr__.const_fun_284.290.exit.1, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.1, label %__hugr__.const_fun_287.338.exit.1, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.1: ; preds = %__hugr__.const_fun_284.290.exit +__hugr__.const_fun_287.338.exit.1: ; preds = %__hugr__.const_fun_287.338.exit %120 = extractvalue { i1, { i1, i64, i1 } } %119, 1 %121 = getelementptr inbounds i8, i8* %111, i64 24 %122 = bitcast i8* %121 to { i1, i64, i1 }* @@ -380,9 +380,9 @@ __hugr__.const_fun_284.290.exit.1: ; preds = %__hugr__.const_fun_ %124 = bitcast i8* %123 to { i1, { i1, i64, i1 } }* %125 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %124, align 4 %.fca.0.extract11.i.2 = extractvalue { i1, { i1, i64, i1 } } %125, 0 - br i1 %.fca.0.extract11.i.2, label %__hugr__.const_fun_284.290.exit.2, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.2, label %__hugr__.const_fun_287.338.exit.2, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.2: ; preds = %__hugr__.const_fun_284.290.exit.1 +__hugr__.const_fun_287.338.exit.2: ; preds = %__hugr__.const_fun_287.338.exit.1 %126 = extractvalue { i1, { i1, i64, i1 } } %125, 1 %127 = getelementptr inbounds i8, i8* %111, i64 48 %128 = bitcast i8* %127 to { i1, i64, i1 }* @@ -391,9 +391,9 @@ __hugr__.const_fun_284.290.exit.2: ; preds = %__hugr__.const_fun_ %130 = bitcast i8* %129 to { i1, { i1, i64, i1 } }* %131 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %130, align 4 %.fca.0.extract11.i.3 = extractvalue { i1, { i1, i64, i1 } } %131, 0 - br i1 %.fca.0.extract11.i.3, label %__hugr__.const_fun_284.290.exit.3, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.3, label %__hugr__.const_fun_287.338.exit.3, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.3: ; preds = %__hugr__.const_fun_284.290.exit.2 +__hugr__.const_fun_287.338.exit.3: ; preds = %__hugr__.const_fun_287.338.exit.2 %132 = extractvalue { i1, { i1, i64, i1 } } %131, 1 %133 = getelementptr inbounds i8, i8* %111, i64 72 %134 = bitcast i8* %133 to { i1, i64, i1 }* @@ -402,9 +402,9 @@ __hugr__.const_fun_284.290.exit.3: ; preds = %__hugr__.const_fun_ %136 = bitcast i8* %135 to { i1, { i1, i64, i1 } }* %137 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %136, align 4 %.fca.0.extract11.i.4 = extractvalue { i1, { i1, i64, i1 } } %137, 0 - br i1 %.fca.0.extract11.i.4, label %__hugr__.const_fun_284.290.exit.4, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.4, label %__hugr__.const_fun_287.338.exit.4, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.4: ; preds = %__hugr__.const_fun_284.290.exit.3 +__hugr__.const_fun_287.338.exit.4: ; preds = %__hugr__.const_fun_287.338.exit.3 %138 = extractvalue { i1, { i1, i64, i1 } } %137, 1 %139 = getelementptr inbounds i8, i8* %111, i64 96 %140 = bitcast i8* %139 to { i1, i64, i1 }* @@ -413,9 +413,9 @@ __hugr__.const_fun_284.290.exit.4: ; preds = %__hugr__.const_fun_ %142 = bitcast i8* %141 to { i1, { i1, i64, i1 } }* %143 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %142, align 4 %.fca.0.extract11.i.5 = extractvalue { i1, { i1, i64, i1 } } %143, 0 - br i1 %.fca.0.extract11.i.5, label %__hugr__.const_fun_284.290.exit.5, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.5, label %__hugr__.const_fun_287.338.exit.5, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.5: ; preds = %__hugr__.const_fun_284.290.exit.4 +__hugr__.const_fun_287.338.exit.5: ; preds = %__hugr__.const_fun_287.338.exit.4 %144 = extractvalue { i1, { i1, i64, i1 } } %143, 1 %145 = getelementptr inbounds i8, i8* %111, i64 120 %146 = bitcast i8* %145 to { i1, i64, i1 }* @@ -424,9 +424,9 @@ __hugr__.const_fun_284.290.exit.5: ; preds = %__hugr__.const_fun_ %148 = bitcast i8* %147 to { i1, { i1, i64, i1 } }* %149 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %148, align 4 %.fca.0.extract11.i.6 = extractvalue { i1, { i1, i64, i1 } } %149, 0 - br i1 %.fca.0.extract11.i.6, label %__hugr__.const_fun_284.290.exit.6, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.6, label %__hugr__.const_fun_287.338.exit.6, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.6: ; preds = %__hugr__.const_fun_284.290.exit.5 +__hugr__.const_fun_287.338.exit.6: ; preds = %__hugr__.const_fun_287.338.exit.5 %150 = extractvalue { i1, { i1, i64, i1 } } %149, 1 %151 = getelementptr inbounds i8, i8* %111, i64 144 %152 = bitcast i8* %151 to { i1, i64, i1 }* @@ -435,9 +435,9 @@ __hugr__.const_fun_284.290.exit.6: ; preds = %__hugr__.const_fun_ %154 = bitcast i8* %153 to { i1, { i1, i64, i1 } }* %155 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %154, align 4 %.fca.0.extract11.i.7 = extractvalue { i1, { i1, i64, i1 } } %155, 0 - br i1 %.fca.0.extract11.i.7, label %__hugr__.const_fun_284.290.exit.7, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.7, label %__hugr__.const_fun_287.338.exit.7, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.7: ; preds = %__hugr__.const_fun_284.290.exit.6 +__hugr__.const_fun_287.338.exit.7: ; preds = %__hugr__.const_fun_287.338.exit.6 %156 = extractvalue { i1, { i1, i64, i1 } } %155, 1 %157 = getelementptr inbounds i8, i8* %111, i64 168 %158 = bitcast i8* %157 to { i1, i64, i1 }* @@ -446,9 +446,9 @@ __hugr__.const_fun_284.290.exit.7: ; preds = %__hugr__.const_fun_ %160 = bitcast i8* %159 to { i1, { i1, i64, i1 } }* %161 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %160, align 4 %.fca.0.extract11.i.8 = extractvalue { i1, { i1, i64, i1 } } %161, 0 - br i1 %.fca.0.extract11.i.8, label %__hugr__.const_fun_284.290.exit.8, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.8, label %__hugr__.const_fun_287.338.exit.8, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.8: ; preds = %__hugr__.const_fun_284.290.exit.7 +__hugr__.const_fun_287.338.exit.8: ; preds = %__hugr__.const_fun_287.338.exit.7 %162 = extractvalue { i1, { i1, i64, i1 } } %161, 1 %163 = getelementptr inbounds i8, i8* %111, i64 192 %164 = bitcast i8* %163 to { i1, i64, i1 }* @@ -457,86 +457,86 @@ __hugr__.const_fun_284.290.exit.8: ; preds = %__hugr__.const_fun_ %166 = bitcast i8* %165 to { i1, { i1, i64, i1 } }* %167 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %166, align 4 %.fca.0.extract11.i.9 = extractvalue { i1, { i1, i64, i1 } } %167, 0 - br i1 %.fca.0.extract11.i.9, label %__hugr__.const_fun_284.290.exit.9, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.9, label %__hugr__.const_fun_287.338.exit.9, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.9: ; preds = %__hugr__.const_fun_284.290.exit.8 +__hugr__.const_fun_287.338.exit.9: ; preds = %__hugr__.const_fun_287.338.exit.8 %168 = extractvalue { i1, { i1, i64, i1 } } %167, 1 %169 = getelementptr inbounds i8, i8* %111, i64 216 %170 = bitcast i8* %169 to { i1, i64, i1 }* store { i1, i64, i1 } %168, { i1, i64, i1 }* %170, align 4 tail call void @heap_free(i8* nonnull %63) tail call void @heap_free(i8* nonnull %64) - br label %__barray_check_bounds.exit888 + br label %__barray_check_bounds.exit882 -cond_165_case_0: ; preds = %cond_exit_165 +cond_169_case_0: ; preds = %cond_exit_169 %171 = load i64, i64* %114, align 4 %172 = or i64 %171, -1024 store i64 %172, i64* %114, align 4 %173 = icmp eq i64 %172, -1 - br i1 %173, label %loop_out139, label %mask_block_err.i886 + br i1 %173, label %loop_out135, label %mask_block_err.i880 -mask_block_err.i886: ; preds = %cond_165_case_0 +mask_block_err.i880: ; preds = %cond_169_case_0 tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit888: ; preds = %__hugr__.const_fun_284.290.exit.9, %cond_exit_165 - %"167_0.0989" = phi i64 [ 0, %__hugr__.const_fun_284.290.exit.9 ], [ %174, %cond_exit_165 ] - %174 = add nuw nsw i64 %"167_0.0989", 1 - %175 = lshr i64 %"167_0.0989", 6 +__barray_check_bounds.exit882: ; preds = %__hugr__.const_fun_287.338.exit.9, %cond_exit_169 + %"172_0.0983" = phi i64 [ 0, %__hugr__.const_fun_287.338.exit.9 ], [ %174, %cond_exit_169 ] + %174 = add nuw nsw i64 %"172_0.0983", 1 + %175 = lshr i64 %"172_0.0983", 6 %176 = getelementptr inbounds i64, i64* %114, i64 %175 %177 = load i64, i64* %176, align 4 - %178 = shl nuw nsw i64 1, %"167_0.0989" + %178 = shl nuw nsw i64 1, %"172_0.0983" %179 = and i64 %177, %178 %.not = icmp eq i64 %179, 0 - br i1 %.not, label %__barray_mask_borrow.exit893, label %cond_exit_165 + br i1 %.not, label %__barray_mask_borrow.exit887, label %cond_exit_169 -__barray_mask_borrow.exit893: ; preds = %__barray_check_bounds.exit888 +__barray_mask_borrow.exit887: ; preds = %__barray_check_bounds.exit882 %180 = xor i64 %177, %178 store i64 %180, i64* %176, align 4 - %181 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %112, i64 %"167_0.0989" + %181 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %112, i64 %"172_0.0983" %182 = load { i1, i64, i1 }, { i1, i64, i1 }* %181, align 4 - %.fca.0.extract511 = extractvalue { i1, i64, i1 } %182, 0 - br i1 %.fca.0.extract511, label %cond_501_case_1, label %cond_exit_165 + %.fca.0.extract505 = extractvalue { i1, i64, i1 } %182, 0 + br i1 %.fca.0.extract505, label %cond_496_case_1, label %cond_exit_169 -cond_exit_165: ; preds = %cond_501_case_1, %__barray_mask_borrow.exit893, %__barray_check_bounds.exit888 - %183 = icmp ult i64 %"167_0.0989", 9 - br i1 %183, label %__barray_check_bounds.exit888, label %cond_165_case_0 +cond_exit_169: ; preds = %cond_496_case_1, %__barray_mask_borrow.exit887, %__barray_check_bounds.exit882 + %183 = icmp ult i64 %"172_0.0983", 9 + br i1 %183, label %__barray_check_bounds.exit882, label %cond_169_case_0 -loop_out139: ; preds = %cond_165_case_0 +loop_out135: ; preds = %cond_169_case_0 tail call void @heap_free(i8* %111) tail call void @heap_free(i8* nonnull %113) %184 = load i64, i64* %87, align 4 %185 = and i64 %184, 1023 store i64 %185, i64* %87, align 4 %186 = icmp eq i64 %185, 0 - br i1 %186, label %__barray_check_none_borrowed.exit898, label %mask_block_err.i897 + br i1 %186, label %__barray_check_none_borrowed.exit892, label %mask_block_err.i891 -__barray_check_none_borrowed.exit898: ; preds = %loop_out139 +__barray_check_none_borrowed.exit892: ; preds = %loop_out135 %187 = tail call i8* @heap_alloc(i64 10) %188 = tail call i8* @heap_alloc(i64 8) %189 = bitcast i8* %188 to i64* store i64 0, i64* %189, align 1 %190 = load { i1, i64, i1 }, { i1, i64, i1 }* %85, align 4 - %.fca.0.extract.i899 = extractvalue { i1, i64, i1 } %190, 0 - %.fca.1.extract.i900 = extractvalue { i1, i64, i1 } %190, 1 - br i1 %.fca.0.extract.i899, label %cond_300_case_1.i, label %cond_300_case_0.i + %.fca.0.extract.i893 = extractvalue { i1, i64, i1 } %190, 0 + %.fca.1.extract.i894 = extractvalue { i1, i64, i1 } %190, 1 + br i1 %.fca.0.extract.i893, label %cond_300_case_1.i, label %cond_300_case_0.i -mask_block_err.i897: ; preds = %loop_out139 +mask_block_err.i891: ; preds = %loop_out135 tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -cond_501_case_1: ; preds = %__barray_mask_borrow.exit893 - %.fca.1.extract512 = extractvalue { i1, i64, i1 } %182, 1 - tail call void @___dec_future_refcount(i64 %.fca.1.extract512) - br label %cond_exit_165 +cond_496_case_1: ; preds = %__barray_mask_borrow.exit887 + %.fca.1.extract506 = extractvalue { i1, i64, i1 } %182, 1 + tail call void @___dec_future_refcount(i64 %.fca.1.extract506) + br label %cond_exit_169 -cond_300_case_0.i: ; preds = %__barray_check_none_borrowed.exit898 +cond_300_case_0.i: ; preds = %__barray_check_none_borrowed.exit892 %.fca.2.extract.i = extractvalue { i1, i64, i1 } %190, 2 br label %__hugr__.array.__read_bool.3.271.exit -cond_300_case_1.i: ; preds = %__barray_check_none_borrowed.exit898 - %read_bool.i = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900) +cond_300_case_1.i: ; preds = %__barray_check_none_borrowed.exit892 + %read_bool.i = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894) br label %__hugr__.array.__read_bool.3.271.exit __hugr__.array.__read_bool.3.271.exit: ; preds = %cond_300_case_0.i, %cond_300_case_1.i @@ -546,17 +546,17 @@ __hugr__.array.__read_bool.3.271.exit: ; preds = %cond_300_case_0.i, %192 = getelementptr inbounds i8, i8* %84, i64 24 %193 = bitcast i8* %192 to { i1, i64, i1 }* %194 = load { i1, i64, i1 }, { i1, i64, i1 }* %193, align 4 - %.fca.0.extract.i899.1 = extractvalue { i1, i64, i1 } %194, 0 - %.fca.1.extract.i900.1 = extractvalue { i1, i64, i1 } %194, 1 - br i1 %.fca.0.extract.i899.1, label %cond_300_case_1.i.1, label %cond_300_case_0.i.1 + %.fca.0.extract.i893.1 = extractvalue { i1, i64, i1 } %194, 0 + %.fca.1.extract.i894.1 = extractvalue { i1, i64, i1 } %194, 1 + br i1 %.fca.0.extract.i893.1, label %cond_300_case_1.i.1, label %cond_300_case_0.i.1 cond_300_case_0.i.1: ; preds = %__hugr__.array.__read_bool.3.271.exit %.fca.2.extract.i.1 = extractvalue { i1, i64, i1 } %194, 2 br label %__hugr__.array.__read_bool.3.271.exit.1 cond_300_case_1.i.1: ; preds = %__hugr__.array.__read_bool.3.271.exit - %read_bool.i.1 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.1) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.1) + %read_bool.i.1 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.1) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.1) br label %__hugr__.array.__read_bool.3.271.exit.1 __hugr__.array.__read_bool.3.271.exit.1: ; preds = %cond_300_case_1.i.1, %cond_300_case_0.i.1 @@ -567,17 +567,17 @@ __hugr__.array.__read_bool.3.271.exit.1: ; preds = %cond_300_case_1.i.1 %197 = getelementptr inbounds i8, i8* %84, i64 48 %198 = bitcast i8* %197 to { i1, i64, i1 }* %199 = load { i1, i64, i1 }, { i1, i64, i1 }* %198, align 4 - %.fca.0.extract.i899.2 = extractvalue { i1, i64, i1 } %199, 0 - %.fca.1.extract.i900.2 = extractvalue { i1, i64, i1 } %199, 1 - br i1 %.fca.0.extract.i899.2, label %cond_300_case_1.i.2, label %cond_300_case_0.i.2 + %.fca.0.extract.i893.2 = extractvalue { i1, i64, i1 } %199, 0 + %.fca.1.extract.i894.2 = extractvalue { i1, i64, i1 } %199, 1 + br i1 %.fca.0.extract.i893.2, label %cond_300_case_1.i.2, label %cond_300_case_0.i.2 cond_300_case_0.i.2: ; preds = %__hugr__.array.__read_bool.3.271.exit.1 %.fca.2.extract.i.2 = extractvalue { i1, i64, i1 } %199, 2 br label %__hugr__.array.__read_bool.3.271.exit.2 cond_300_case_1.i.2: ; preds = %__hugr__.array.__read_bool.3.271.exit.1 - %read_bool.i.2 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.2) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.2) + %read_bool.i.2 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.2) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.2) br label %__hugr__.array.__read_bool.3.271.exit.2 __hugr__.array.__read_bool.3.271.exit.2: ; preds = %cond_300_case_1.i.2, %cond_300_case_0.i.2 @@ -588,17 +588,17 @@ __hugr__.array.__read_bool.3.271.exit.2: ; preds = %cond_300_case_1.i.2 %202 = getelementptr inbounds i8, i8* %84, i64 72 %203 = bitcast i8* %202 to { i1, i64, i1 }* %204 = load { i1, i64, i1 }, { i1, i64, i1 }* %203, align 4 - %.fca.0.extract.i899.3 = extractvalue { i1, i64, i1 } %204, 0 - %.fca.1.extract.i900.3 = extractvalue { i1, i64, i1 } %204, 1 - br i1 %.fca.0.extract.i899.3, label %cond_300_case_1.i.3, label %cond_300_case_0.i.3 + %.fca.0.extract.i893.3 = extractvalue { i1, i64, i1 } %204, 0 + %.fca.1.extract.i894.3 = extractvalue { i1, i64, i1 } %204, 1 + br i1 %.fca.0.extract.i893.3, label %cond_300_case_1.i.3, label %cond_300_case_0.i.3 cond_300_case_0.i.3: ; preds = %__hugr__.array.__read_bool.3.271.exit.2 %.fca.2.extract.i.3 = extractvalue { i1, i64, i1 } %204, 2 br label %__hugr__.array.__read_bool.3.271.exit.3 cond_300_case_1.i.3: ; preds = %__hugr__.array.__read_bool.3.271.exit.2 - %read_bool.i.3 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.3) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.3) + %read_bool.i.3 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.3) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.3) br label %__hugr__.array.__read_bool.3.271.exit.3 __hugr__.array.__read_bool.3.271.exit.3: ; preds = %cond_300_case_1.i.3, %cond_300_case_0.i.3 @@ -609,17 +609,17 @@ __hugr__.array.__read_bool.3.271.exit.3: ; preds = %cond_300_case_1.i.3 %207 = getelementptr inbounds i8, i8* %84, i64 96 %208 = bitcast i8* %207 to { i1, i64, i1 }* %209 = load { i1, i64, i1 }, { i1, i64, i1 }* %208, align 4 - %.fca.0.extract.i899.4 = extractvalue { i1, i64, i1 } %209, 0 - %.fca.1.extract.i900.4 = extractvalue { i1, i64, i1 } %209, 1 - br i1 %.fca.0.extract.i899.4, label %cond_300_case_1.i.4, label %cond_300_case_0.i.4 + %.fca.0.extract.i893.4 = extractvalue { i1, i64, i1 } %209, 0 + %.fca.1.extract.i894.4 = extractvalue { i1, i64, i1 } %209, 1 + br i1 %.fca.0.extract.i893.4, label %cond_300_case_1.i.4, label %cond_300_case_0.i.4 cond_300_case_0.i.4: ; preds = %__hugr__.array.__read_bool.3.271.exit.3 %.fca.2.extract.i.4 = extractvalue { i1, i64, i1 } %209, 2 br label %__hugr__.array.__read_bool.3.271.exit.4 cond_300_case_1.i.4: ; preds = %__hugr__.array.__read_bool.3.271.exit.3 - %read_bool.i.4 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.4) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.4) + %read_bool.i.4 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.4) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.4) br label %__hugr__.array.__read_bool.3.271.exit.4 __hugr__.array.__read_bool.3.271.exit.4: ; preds = %cond_300_case_1.i.4, %cond_300_case_0.i.4 @@ -630,17 +630,17 @@ __hugr__.array.__read_bool.3.271.exit.4: ; preds = %cond_300_case_1.i.4 %212 = getelementptr inbounds i8, i8* %84, i64 120 %213 = bitcast i8* %212 to { i1, i64, i1 }* %214 = load { i1, i64, i1 }, { i1, i64, i1 }* %213, align 4 - %.fca.0.extract.i899.5 = extractvalue { i1, i64, i1 } %214, 0 - %.fca.1.extract.i900.5 = extractvalue { i1, i64, i1 } %214, 1 - br i1 %.fca.0.extract.i899.5, label %cond_300_case_1.i.5, label %cond_300_case_0.i.5 + %.fca.0.extract.i893.5 = extractvalue { i1, i64, i1 } %214, 0 + %.fca.1.extract.i894.5 = extractvalue { i1, i64, i1 } %214, 1 + br i1 %.fca.0.extract.i893.5, label %cond_300_case_1.i.5, label %cond_300_case_0.i.5 cond_300_case_0.i.5: ; preds = %__hugr__.array.__read_bool.3.271.exit.4 %.fca.2.extract.i.5 = extractvalue { i1, i64, i1 } %214, 2 br label %__hugr__.array.__read_bool.3.271.exit.5 cond_300_case_1.i.5: ; preds = %__hugr__.array.__read_bool.3.271.exit.4 - %read_bool.i.5 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.5) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.5) + %read_bool.i.5 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.5) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.5) br label %__hugr__.array.__read_bool.3.271.exit.5 __hugr__.array.__read_bool.3.271.exit.5: ; preds = %cond_300_case_1.i.5, %cond_300_case_0.i.5 @@ -651,17 +651,17 @@ __hugr__.array.__read_bool.3.271.exit.5: ; preds = %cond_300_case_1.i.5 %217 = getelementptr inbounds i8, i8* %84, i64 144 %218 = bitcast i8* %217 to { i1, i64, i1 }* %219 = load { i1, i64, i1 }, { i1, i64, i1 }* %218, align 4 - %.fca.0.extract.i899.6 = extractvalue { i1, i64, i1 } %219, 0 - %.fca.1.extract.i900.6 = extractvalue { i1, i64, i1 } %219, 1 - br i1 %.fca.0.extract.i899.6, label %cond_300_case_1.i.6, label %cond_300_case_0.i.6 + %.fca.0.extract.i893.6 = extractvalue { i1, i64, i1 } %219, 0 + %.fca.1.extract.i894.6 = extractvalue { i1, i64, i1 } %219, 1 + br i1 %.fca.0.extract.i893.6, label %cond_300_case_1.i.6, label %cond_300_case_0.i.6 cond_300_case_0.i.6: ; preds = %__hugr__.array.__read_bool.3.271.exit.5 %.fca.2.extract.i.6 = extractvalue { i1, i64, i1 } %219, 2 br label %__hugr__.array.__read_bool.3.271.exit.6 cond_300_case_1.i.6: ; preds = %__hugr__.array.__read_bool.3.271.exit.5 - %read_bool.i.6 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.6) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.6) + %read_bool.i.6 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.6) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.6) br label %__hugr__.array.__read_bool.3.271.exit.6 __hugr__.array.__read_bool.3.271.exit.6: ; preds = %cond_300_case_1.i.6, %cond_300_case_0.i.6 @@ -672,17 +672,17 @@ __hugr__.array.__read_bool.3.271.exit.6: ; preds = %cond_300_case_1.i.6 %222 = getelementptr inbounds i8, i8* %84, i64 168 %223 = bitcast i8* %222 to { i1, i64, i1 }* %224 = load { i1, i64, i1 }, { i1, i64, i1 }* %223, align 4 - %.fca.0.extract.i899.7 = extractvalue { i1, i64, i1 } %224, 0 - %.fca.1.extract.i900.7 = extractvalue { i1, i64, i1 } %224, 1 - br i1 %.fca.0.extract.i899.7, label %cond_300_case_1.i.7, label %cond_300_case_0.i.7 + %.fca.0.extract.i893.7 = extractvalue { i1, i64, i1 } %224, 0 + %.fca.1.extract.i894.7 = extractvalue { i1, i64, i1 } %224, 1 + br i1 %.fca.0.extract.i893.7, label %cond_300_case_1.i.7, label %cond_300_case_0.i.7 cond_300_case_0.i.7: ; preds = %__hugr__.array.__read_bool.3.271.exit.6 %.fca.2.extract.i.7 = extractvalue { i1, i64, i1 } %224, 2 br label %__hugr__.array.__read_bool.3.271.exit.7 cond_300_case_1.i.7: ; preds = %__hugr__.array.__read_bool.3.271.exit.6 - %read_bool.i.7 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.7) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.7) + %read_bool.i.7 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.7) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.7) br label %__hugr__.array.__read_bool.3.271.exit.7 __hugr__.array.__read_bool.3.271.exit.7: ; preds = %cond_300_case_1.i.7, %cond_300_case_0.i.7 @@ -693,17 +693,17 @@ __hugr__.array.__read_bool.3.271.exit.7: ; preds = %cond_300_case_1.i.7 %227 = getelementptr inbounds i8, i8* %84, i64 192 %228 = bitcast i8* %227 to { i1, i64, i1 }* %229 = load { i1, i64, i1 }, { i1, i64, i1 }* %228, align 4 - %.fca.0.extract.i899.8 = extractvalue { i1, i64, i1 } %229, 0 - %.fca.1.extract.i900.8 = extractvalue { i1, i64, i1 } %229, 1 - br i1 %.fca.0.extract.i899.8, label %cond_300_case_1.i.8, label %cond_300_case_0.i.8 + %.fca.0.extract.i893.8 = extractvalue { i1, i64, i1 } %229, 0 + %.fca.1.extract.i894.8 = extractvalue { i1, i64, i1 } %229, 1 + br i1 %.fca.0.extract.i893.8, label %cond_300_case_1.i.8, label %cond_300_case_0.i.8 cond_300_case_0.i.8: ; preds = %__hugr__.array.__read_bool.3.271.exit.7 %.fca.2.extract.i.8 = extractvalue { i1, i64, i1 } %229, 2 br label %__hugr__.array.__read_bool.3.271.exit.8 cond_300_case_1.i.8: ; preds = %__hugr__.array.__read_bool.3.271.exit.7 - %read_bool.i.8 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.8) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.8) + %read_bool.i.8 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.8) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.8) br label %__hugr__.array.__read_bool.3.271.exit.8 __hugr__.array.__read_bool.3.271.exit.8: ; preds = %cond_300_case_1.i.8, %cond_300_case_0.i.8 @@ -714,17 +714,17 @@ __hugr__.array.__read_bool.3.271.exit.8: ; preds = %cond_300_case_1.i.8 %232 = getelementptr inbounds i8, i8* %84, i64 216 %233 = bitcast i8* %232 to { i1, i64, i1 }* %234 = load { i1, i64, i1 }, { i1, i64, i1 }* %233, align 4 - %.fca.0.extract.i899.9 = extractvalue { i1, i64, i1 } %234, 0 - %.fca.1.extract.i900.9 = extractvalue { i1, i64, i1 } %234, 1 - br i1 %.fca.0.extract.i899.9, label %cond_300_case_1.i.9, label %cond_300_case_0.i.9 + %.fca.0.extract.i893.9 = extractvalue { i1, i64, i1 } %234, 0 + %.fca.1.extract.i894.9 = extractvalue { i1, i64, i1 } %234, 1 + br i1 %.fca.0.extract.i893.9, label %cond_300_case_1.i.9, label %cond_300_case_0.i.9 cond_300_case_0.i.9: ; preds = %__hugr__.array.__read_bool.3.271.exit.8 %.fca.2.extract.i.9 = extractvalue { i1, i64, i1 } %234, 2 br label %__hugr__.array.__read_bool.3.271.exit.9 cond_300_case_1.i.9: ; preds = %__hugr__.array.__read_bool.3.271.exit.8 - %read_bool.i.9 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.9) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.9) + %read_bool.i.9 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.9) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.9) br label %__hugr__.array.__read_bool.3.271.exit.9 __hugr__.array.__read_bool.3.271.exit.9: ; preds = %cond_300_case_1.i.9, %cond_300_case_0.i.9 @@ -738,9 +738,9 @@ __hugr__.array.__read_bool.3.271.exit.9: ; preds = %cond_300_case_1.i.9 %238 = and i64 %237, 1023 store i64 %238, i64* %189, align 4 %239 = icmp eq i64 %238, 0 - br i1 %239, label %__barray_check_none_borrowed.exit905, label %mask_block_err.i904 + br i1 %239, label %__barray_check_none_borrowed.exit899, label %mask_block_err.i898 -__barray_check_none_borrowed.exit905: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 +__barray_check_none_borrowed.exit899: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 %out_arr_alloca = alloca <{ i32, i32, i1*, i1* }>, align 8 %x_ptr = getelementptr inbounds <{ i32, i32, i1*, i1* }>, <{ i32, i32, i1*, i1* }>* %out_arr_alloca, i64 0, i32 0 %y_ptr = getelementptr inbounds <{ i32, i32, i1*, i1* }>, <{ i32, i32, i1*, i1* }>* %out_arr_alloca, i64 0, i32 1 @@ -756,52 +756,52 @@ __barray_check_none_borrowed.exit905: ; preds = %__hugr__.array.__re store i8* %187, i8** %242, align 8 store i1* %.sub, i1** %mask_ptr, align 8 call void @print_bool_arr(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @res_cs.46C3C4B5.0, i64 0, i64 0), i64 15, <{ i32, i32, i1*, i1* }>* nonnull %out_arr_alloca) - br label %__barray_check_bounds.exit913 + br label %__barray_check_bounds.exit907 -mask_block_err.i904: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 +mask_block_err.i898: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit913: ; preds = %cond_exit_95.1, %__barray_check_none_borrowed.exit905 - %"90_0.sroa.0.0972" = phi i64 [ 0, %__barray_check_none_borrowed.exit905 ], [ %252, %cond_exit_95.1 ] - %243 = or i64 %"90_0.sroa.0.0972", 1 - %244 = lshr i64 %"90_0.sroa.0.0972", 6 +__barray_check_bounds.exit907: ; preds = %cond_exit_95.1, %__barray_check_none_borrowed.exit899 + %"90_0.sroa.0.0966" = phi i64 [ 0, %__barray_check_none_borrowed.exit899 ], [ %252, %cond_exit_95.1 ] + %243 = or i64 %"90_0.sroa.0.0966", 1 + %244 = lshr i64 %"90_0.sroa.0.0966", 6 %245 = getelementptr inbounds i64, i64* %7, i64 %244 %246 = load i64, i64* %245, align 4 - %247 = and i64 %"90_0.sroa.0.0972", 62 + %247 = and i64 %"90_0.sroa.0.0966", 62 %248 = shl nuw i64 1, %247 %249 = and i64 %246, %248 - %.not.i914 = icmp eq i64 %249, 0 - br i1 %.not.i914, label %panic.i915, label %cond_exit_95 + %.not.i908 = icmp eq i64 %249, 0 + br i1 %.not.i908, label %panic.i909, label %cond_exit_95 -panic.i915: ; preds = %cond_exit_95, %__barray_check_bounds.exit913 +panic.i909: ; preds = %cond_exit_95, %__barray_check_bounds.exit907 call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -cond_exit_95: ; preds = %__barray_check_bounds.exit913 +cond_exit_95: ; preds = %__barray_check_bounds.exit907 %250 = xor i64 %246, %248 store i64 %250, i64* %245, align 4 - %251 = getelementptr inbounds i64, i64* %5, i64 %"90_0.sroa.0.0972" - store i64 %"90_0.sroa.0.0972", i64* %251, align 4 - %252 = add nuw nsw i64 %"90_0.sroa.0.0972", 2 - %253 = lshr i64 %"90_0.sroa.0.0972", 6 + %251 = getelementptr inbounds i64, i64* %5, i64 %"90_0.sroa.0.0966" + store i64 %"90_0.sroa.0.0966", i64* %251, align 4 + %252 = add nuw nsw i64 %"90_0.sroa.0.0966", 2 + %253 = lshr i64 %"90_0.sroa.0.0966", 6 %254 = getelementptr inbounds i64, i64* %7, i64 %253 %255 = load i64, i64* %254, align 4 %256 = and i64 %243, 63 %257 = shl nuw i64 1, %256 %258 = and i64 %255, %257 - %.not.i914.1 = icmp eq i64 %258, 0 - br i1 %.not.i914.1, label %panic.i915, label %cond_exit_95.1 + %.not.i908.1 = icmp eq i64 %258, 0 + br i1 %.not.i908.1, label %panic.i909, label %cond_exit_95.1 cond_exit_95.1: ; preds = %cond_exit_95 %259 = xor i64 %255, %257 store i64 %259, i64* %254, align 4 %260 = getelementptr inbounds i64, i64* %5, i64 %243 store i64 %243, i64* %260, align 4 - %exitcond983.not.1 = icmp eq i64 %252, 100 - br i1 %exitcond983.not.1, label %loop_out212, label %__barray_check_bounds.exit913 + %exitcond977.not.1 = icmp eq i64 %252, 100 + br i1 %exitcond977.not.1, label %loop_out208, label %__barray_check_bounds.exit907 -loop_out212: ; preds = %cond_exit_95.1 +loop_out208: ; preds = %cond_exit_95.1 %261 = getelementptr inbounds i8, i8* %6, i64 8 %262 = bitcast i8* %261 to i64* %263 = load i64, i64* %262, align 4 @@ -811,9 +811,9 @@ loop_out212: ; preds = %cond_exit_95.1 %266 = icmp eq i64 %265, 0 %267 = icmp eq i64 %264, 0 %or.cond = select i1 %266, i1 %267, i1 false - br i1 %or.cond, label %__barray_check_none_borrowed.exit921, label %mask_block_err.i920 + br i1 %or.cond, label %__barray_check_none_borrowed.exit915, label %mask_block_err.i914 -__barray_check_none_borrowed.exit921: ; preds = %loop_out212 +__barray_check_none_borrowed.exit915: ; preds = %loop_out208 %268 = call i8* @heap_alloc(i64 800) %269 = bitcast i8* %268 to i64* %270 = call i8* @heap_alloc(i64 16) @@ -827,62 +827,62 @@ __barray_check_none_borrowed.exit921: ; preds = %loop_out212 %274 = load i64, i64* %7, align 4 %275 = icmp eq i64 %274, 0 %276 = icmp eq i64 %273, 0 - %or.cond986 = select i1 %275, i1 %276, i1 false - br i1 %or.cond986, label %__barray_check_none_borrowed.exit926, label %mask_block_err.i925 + %or.cond980 = select i1 %275, i1 %276, i1 false + br i1 %or.cond980, label %__barray_check_none_borrowed.exit920, label %mask_block_err.i919 -mask_block_err.i920: ; preds = %loop_out212 +mask_block_err.i914: ; preds = %loop_out208 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_none_borrowed.exit926: ; preds = %__barray_check_none_borrowed.exit921 - %out_arr_alloca287 = alloca <{ i32, i32, i64*, i1* }>, align 8 - %x_ptr288 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 0 - %y_ptr289 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 1 - %arr_ptr290 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 2 - %mask_ptr291 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 3 +__barray_check_none_borrowed.exit920: ; preds = %__barray_check_none_borrowed.exit915 + %out_arr_alloca282 = alloca <{ i32, i32, i64*, i1* }>, align 8 + %x_ptr283 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 0 + %y_ptr284 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 1 + %arr_ptr285 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 2 + %mask_ptr286 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 3 %277 = alloca [100 x i1], align 1 - %.sub635 = getelementptr inbounds [100 x i1], [100 x i1]* %277, i64 0, i64 0 + %.sub629 = getelementptr inbounds [100 x i1], [100 x i1]* %277, i64 0, i64 0 %278 = bitcast [100 x i1]* %277 to i8* call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(100) %278, i8 0, i64 100, i1 false) - store i32 100, i32* %x_ptr288, align 8 - store i32 1, i32* %y_ptr289, align 4 - %279 = bitcast i64** %arr_ptr290 to i8** + store i32 100, i32* %x_ptr283, align 8 + store i32 1, i32* %y_ptr284, align 4 + %279 = bitcast i64** %arr_ptr285 to i8** store i8* %4, i8** %279, align 8 - store i1* %.sub635, i1** %mask_ptr291, align 8 - call void @print_int_arr(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @res_is.F21393DB.0, i64 0, i64 0), i64 14, <{ i32, i32, i64*, i1* }>* nonnull %out_arr_alloca287) - br label %__barray_check_bounds.exit934 + store i1* %.sub629, i1** %mask_ptr286, align 8 + call void @print_int_arr(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @res_is.F21393DB.0, i64 0, i64 0), i64 14, <{ i32, i32, i64*, i1* }>* nonnull %out_arr_alloca282) + br label %__barray_check_bounds.exit928 -mask_block_err.i925: ; preds = %__barray_check_none_borrowed.exit921 +mask_block_err.i919: ; preds = %__barray_check_none_borrowed.exit915 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit934: ; preds = %cond_exit_130, %__barray_check_none_borrowed.exit926 - %"125_0.sroa.0.0974" = phi i64 [ 0, %__barray_check_none_borrowed.exit926 ], [ %280, %cond_exit_130 ] - %280 = add nuw nsw i64 %"125_0.sroa.0.0974", 1 - %281 = lshr i64 %"125_0.sroa.0.0974", 6 +__barray_check_bounds.exit928: ; preds = %cond_exit_130, %__barray_check_none_borrowed.exit920 + %"125_0.sroa.0.0968" = phi i64 [ 0, %__barray_check_none_borrowed.exit920 ], [ %280, %cond_exit_130 ] + %280 = add nuw nsw i64 %"125_0.sroa.0.0968", 1 + %281 = lshr i64 %"125_0.sroa.0.0968", 6 %282 = getelementptr inbounds i64, i64* %3, i64 %281 %283 = load i64, i64* %282, align 4 - %284 = and i64 %"125_0.sroa.0.0974", 63 + %284 = and i64 %"125_0.sroa.0.0968", 63 %285 = shl nuw i64 1, %284 %286 = and i64 %283, %285 - %.not.i935 = icmp eq i64 %286, 0 - br i1 %.not.i935, label %panic.i936, label %cond_exit_130 + %.not.i929 = icmp eq i64 %286, 0 + br i1 %.not.i929, label %panic.i930, label %cond_exit_130 -panic.i936: ; preds = %__barray_check_bounds.exit934 +panic.i930: ; preds = %__barray_check_bounds.exit928 call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -cond_exit_130: ; preds = %__barray_check_bounds.exit934 - %287 = sitofp i64 %"125_0.sroa.0.0974" to double +cond_exit_130: ; preds = %__barray_check_bounds.exit928 + %287 = sitofp i64 %"125_0.sroa.0.0968" to double %288 = fmul double %287, 6.250000e-02 %289 = xor i64 %283, %285 store i64 %289, i64* %282, align 4 - %290 = getelementptr inbounds double, double* %1, i64 %"125_0.sroa.0.0974" + %290 = getelementptr inbounds double, double* %1, i64 %"125_0.sroa.0.0968" store double %288, double* %290, align 8 - %exitcond984.not = icmp eq i64 %280, 100 - br i1 %exitcond984.not, label %loop_out299, label %__barray_check_bounds.exit934 + %exitcond978.not = icmp eq i64 %280, 100 + br i1 %exitcond978.not, label %loop_out294, label %__barray_check_bounds.exit928 -loop_out299: ; preds = %cond_exit_130 +loop_out294: ; preds = %cond_exit_130 %291 = getelementptr inbounds i8, i8* %2, i64 8 %292 = bitcast i8* %291 to i64* %293 = load i64, i64* %292, align 4 @@ -891,10 +891,10 @@ loop_out299: ; preds = %cond_exit_130 %295 = load i64, i64* %3, align 4 %296 = icmp eq i64 %295, 0 %297 = icmp eq i64 %294, 0 - %or.cond987 = select i1 %296, i1 %297, i1 false - br i1 %or.cond987, label %__barray_check_none_borrowed.exit942, label %mask_block_err.i941 + %or.cond981 = select i1 %296, i1 %297, i1 false + br i1 %or.cond981, label %__barray_check_none_borrowed.exit936, label %mask_block_err.i935 -__barray_check_none_borrowed.exit942: ; preds = %loop_out299 +__barray_check_none_borrowed.exit936: ; preds = %loop_out294 %298 = call i8* @heap_alloc(i64 800) %299 = bitcast i8* %298 to double* %300 = call i8* @heap_alloc(i64 16) @@ -908,32 +908,32 @@ __barray_check_none_borrowed.exit942: ; preds = %loop_out299 %304 = load i64, i64* %3, align 4 %305 = icmp eq i64 %304, 0 %306 = icmp eq i64 %303, 0 - %or.cond988 = select i1 %305, i1 %306, i1 false - br i1 %or.cond988, label %__barray_check_none_borrowed.exit947, label %mask_block_err.i946 + %or.cond982 = select i1 %305, i1 %306, i1 false + br i1 %or.cond982, label %__barray_check_none_borrowed.exit941, label %mask_block_err.i940 -mask_block_err.i941: ; preds = %loop_out299 +mask_block_err.i935: ; preds = %loop_out294 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_none_borrowed.exit947: ; preds = %__barray_check_none_borrowed.exit942 - %out_arr_alloca377 = alloca <{ i32, i32, double*, i1* }>, align 8 - %x_ptr378 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 0 - %y_ptr379 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 1 - %arr_ptr380 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 2 - %mask_ptr381 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 3 +__barray_check_none_borrowed.exit941: ; preds = %__barray_check_none_borrowed.exit936 + %out_arr_alloca371 = alloca <{ i32, i32, double*, i1* }>, align 8 + %x_ptr372 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 0 + %y_ptr373 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 1 + %arr_ptr374 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 2 + %mask_ptr375 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 3 %307 = alloca [100 x i1], align 1 - %.sub736 = getelementptr inbounds [100 x i1], [100 x i1]* %307, i64 0, i64 0 + %.sub730 = getelementptr inbounds [100 x i1], [100 x i1]* %307, i64 0, i64 0 %308 = bitcast [100 x i1]* %307 to i8* call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(100) %308, i8 0, i64 100, i1 false) - store i32 100, i32* %x_ptr378, align 8 - store i32 1, i32* %y_ptr379, align 4 - %309 = bitcast double** %arr_ptr380 to i8** + store i32 100, i32* %x_ptr372, align 8 + store i32 1, i32* %y_ptr373, align 4 + %309 = bitcast double** %arr_ptr374 to i8** store i8* %0, i8** %309, align 8 - store i1* %.sub736, i1** %mask_ptr381, align 8 - call void @print_float_arr(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @res_fs.CBD4AF54.0, i64 0, i64 0), i64 16, <{ i32, i32, double*, i1* }>* nonnull %out_arr_alloca377) + store i1* %.sub730, i1** %mask_ptr375, align 8 + call void @print_float_arr(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @res_fs.CBD4AF54.0, i64 0, i64 0), i64 16, <{ i32, i32, double*, i1* }>* nonnull %out_arr_alloca371) ret void -mask_block_err.i946: ; preds = %__barray_check_none_borrowed.exit942 +mask_block_err.i940: ; preds = %__barray_check_none_borrowed.exit936 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable } diff --git a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-windows-msvc-measure_qb_array/measure_qb_array_x86_64-windows-msvc b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-windows-msvc-measure_qb_array/measure_qb_array_x86_64-windows-msvc index 48a0a576f..112e46c28 100644 --- a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-windows-msvc-measure_qb_array/measure_qb_array_x86_64-windows-msvc +++ b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-windows-msvc-measure_qb_array/measure_qb_array_x86_64-windows-msvc @@ -38,8 +38,8 @@ entry: br label %cond_20_case_1.i cond_20_case_1.i: ; preds = %cond_exit_20.i, %entry - %"15_0.sroa.0.0295.i" = phi i64 [ 0, %entry ], [ %5, %cond_exit_20.i ] - %5 = add nuw nsw i64 %"15_0.sroa.0.0295.i", 1 + %"15_0.sroa.0.0294.i" = phi i64 [ 0, %entry ], [ %5, %cond_exit_20.i ] + %5 = add nuw nsw i64 %"15_0.sroa.0.0294.i", 1 %qalloc.i.i = tail call i64 @___qalloc() %not_max.not.i.i = icmp eq i64 %qalloc.i.i, -1 br i1 %not_max.not.i.i, label %id_bb.i.i, label %reset_bb.i.i @@ -59,10 +59,10 @@ cond_217_case_0.i.i: ; preds = %id_bb.i.i unreachable __barray_check_bounds.exit.i: ; preds = %id_bb.i.i - %8 = lshr i64 %"15_0.sroa.0.0295.i", 6 + %8 = lshr i64 %"15_0.sroa.0.0294.i", 6 %9 = getelementptr inbounds i64, i64* %4, i64 %8 %10 = load i64, i64* %9, align 4 - %11 = shl nuw nsw i64 1, %"15_0.sroa.0.0295.i" + %11 = shl nuw nsw i64 1, %"15_0.sroa.0.0294.i" %12 = and i64 %10, %11 %.not.i.i = icmp eq i64 %12, 0 br i1 %.not.i.i, label %panic.i.i, label %cond_exit_20.i @@ -75,7 +75,7 @@ cond_exit_20.i: ; preds = %__barray_check_boun %.fca.1.extract.i.i = extractvalue { i1, i64 } %7, 1 %13 = xor i64 %10, %11 store i64 %13, i64* %9, align 4 - %14 = getelementptr inbounds i64, i64* %2, i64 %"15_0.sroa.0.0295.i" + %14 = getelementptr inbounds i64, i64* %2, i64 %"15_0.sroa.0.0294.i" store i64 %.fca.1.extract.i.i, i64* %14, align 4 %exitcond.not.i = icmp eq i64 %5, 10 br i1 %exitcond.not.i, label %loop_out.i, label %cond_20_case_1.i @@ -83,10 +83,10 @@ cond_exit_20.i: ; preds = %__barray_check_boun loop_out.i: ; preds = %cond_exit_20.i %15 = load i64, i64* %4, align 4 %16 = and i64 %15, 1 - %.not.i259.i = icmp eq i64 %16, 0 - br i1 %.not.i259.i, label %__barray_mask_borrow.exit.i, label %panic.i260.i + %.not.i258.i = icmp eq i64 %16, 0 + br i1 %.not.i258.i, label %__barray_mask_borrow.exit.i, label %panic.i259.i -panic.i260.i: ; preds = %loop_out.i +panic.i259.i: ; preds = %loop_out.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable @@ -97,27 +97,27 @@ __barray_mask_borrow.exit.i: ; preds = %loop_out.i tail call void @___rxy(i64 %18, double 0x400921FB54442D18, double 0.000000e+00) %19 = load i64, i64* %4, align 4 %20 = and i64 %19, 1 - %.not.i261.i = icmp eq i64 %20, 0 - br i1 %.not.i261.i, label %panic.i262.i, label %__barray_mask_return.exit263.i + %.not.i260.i = icmp eq i64 %20, 0 + br i1 %.not.i260.i, label %panic.i261.i, label %__barray_mask_return.exit262.i -panic.i262.i: ; preds = %__barray_mask_borrow.exit.i +panic.i261.i: ; preds = %__barray_mask_borrow.exit.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit263.i: ; preds = %__barray_mask_borrow.exit.i +__barray_mask_return.exit262.i: ; preds = %__barray_mask_borrow.exit.i %21 = xor i64 %19, 1 store i64 %21, i64* %4, align 4 store i64 %18, i64* %2, align 4 %22 = load i64, i64* %4, align 4 %23 = and i64 %22, 4 - %.not.i264.i = icmp eq i64 %23, 0 - br i1 %.not.i264.i, label %__barray_mask_borrow.exit266.i, label %panic.i265.i + %.not.i263.i = icmp eq i64 %23, 0 + br i1 %.not.i263.i, label %__barray_mask_borrow.exit265.i, label %panic.i264.i -panic.i265.i: ; preds = %__barray_mask_return.exit263.i +panic.i264.i: ; preds = %__barray_mask_return.exit262.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit266.i: ; preds = %__barray_mask_return.exit263.i +__barray_mask_borrow.exit265.i: ; preds = %__barray_mask_return.exit262.i %24 = xor i64 %22, 4 store i64 %24, i64* %4, align 4 %25 = getelementptr inbounds i8, i8* %1, i64 16 @@ -126,27 +126,27 @@ __barray_mask_borrow.exit266.i: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %27, double 0x400921FB54442D18, double 0.000000e+00) %28 = load i64, i64* %4, align 4 %29 = and i64 %28, 4 - %.not.i267.i = icmp eq i64 %29, 0 - br i1 %.not.i267.i, label %panic.i268.i, label %__barray_mask_return.exit269.i + %.not.i266.i = icmp eq i64 %29, 0 + br i1 %.not.i266.i, label %panic.i267.i, label %__barray_mask_return.exit268.i -panic.i268.i: ; preds = %__barray_mask_borrow.exit266.i +panic.i267.i: ; preds = %__barray_mask_borrow.exit265.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit269.i: ; preds = %__barray_mask_borrow.exit266.i +__barray_mask_return.exit268.i: ; preds = %__barray_mask_borrow.exit265.i %30 = xor i64 %28, 4 store i64 %30, i64* %4, align 4 store i64 %27, i64* %26, align 4 %31 = load i64, i64* %4, align 4 %32 = and i64 %31, 8 - %.not.i270.i = icmp eq i64 %32, 0 - br i1 %.not.i270.i, label %__barray_mask_borrow.exit272.i, label %panic.i271.i + %.not.i269.i = icmp eq i64 %32, 0 + br i1 %.not.i269.i, label %__barray_mask_borrow.exit271.i, label %panic.i270.i -panic.i271.i: ; preds = %__barray_mask_return.exit269.i +panic.i270.i: ; preds = %__barray_mask_return.exit268.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit272.i: ; preds = %__barray_mask_return.exit269.i +__barray_mask_borrow.exit271.i: ; preds = %__barray_mask_return.exit268.i %33 = xor i64 %31, 8 store i64 %33, i64* %4, align 4 %34 = getelementptr inbounds i8, i8* %1, i64 24 @@ -155,27 +155,27 @@ __barray_mask_borrow.exit272.i: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %36, double 0x400921FB54442D18, double 0.000000e+00) %37 = load i64, i64* %4, align 4 %38 = and i64 %37, 8 - %.not.i273.i = icmp eq i64 %38, 0 - br i1 %.not.i273.i, label %panic.i274.i, label %__barray_mask_return.exit275.i + %.not.i272.i = icmp eq i64 %38, 0 + br i1 %.not.i272.i, label %panic.i273.i, label %__barray_mask_return.exit274.i -panic.i274.i: ; preds = %__barray_mask_borrow.exit272.i +panic.i273.i: ; preds = %__barray_mask_borrow.exit271.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit275.i: ; preds = %__barray_mask_borrow.exit272.i +__barray_mask_return.exit274.i: ; preds = %__barray_mask_borrow.exit271.i %39 = xor i64 %37, 8 store i64 %39, i64* %4, align 4 store i64 %36, i64* %35, align 4 %40 = load i64, i64* %4, align 4 %41 = and i64 %40, 512 - %.not.i276.i = icmp eq i64 %41, 0 - br i1 %.not.i276.i, label %__barray_mask_borrow.exit278.i, label %panic.i277.i + %.not.i275.i = icmp eq i64 %41, 0 + br i1 %.not.i275.i, label %__barray_mask_borrow.exit277.i, label %panic.i276.i -panic.i277.i: ; preds = %__barray_mask_return.exit275.i +panic.i276.i: ; preds = %__barray_mask_return.exit274.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit278.i: ; preds = %__barray_mask_return.exit275.i +__barray_mask_borrow.exit277.i: ; preds = %__barray_mask_return.exit274.i %42 = xor i64 %40, 512 store i64 %42, i64* %4, align 4 %43 = getelementptr inbounds i8, i8* %1, i64 72 @@ -184,14 +184,14 @@ __barray_mask_borrow.exit278.i: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %45, double 0x400921FB54442D18, double 0.000000e+00) %46 = load i64, i64* %4, align 4 %47 = and i64 %46, 512 - %.not.i279.i = icmp eq i64 %47, 0 - br i1 %.not.i279.i, label %panic.i280.i, label %__barray_mask_return.exit281.i + %.not.i278.i = icmp eq i64 %47, 0 + br i1 %.not.i278.i, label %panic.i279.i, label %__barray_mask_return.exit280.i -panic.i280.i: ; preds = %__barray_mask_borrow.exit278.i +panic.i279.i: ; preds = %__barray_mask_borrow.exit277.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit281.i: ; preds = %__barray_mask_borrow.exit278.i +__barray_mask_return.exit280.i: ; preds = %__barray_mask_borrow.exit277.i %48 = xor i64 %46, 512 store i64 %48, i64* %4, align 4 store i64 %45, i64* %44, align 4 @@ -212,19 +212,19 @@ mask_block_ok.i.i.i.i: ; preds = %cond_exit_353.i.i "__hugr__.$measure_array$$n(10).277.exit.i": ; preds = %mask_block_ok.i.i.i.i tail call void @heap_free(i8* nonnull %1) tail call void @heap_free(i8* nonnull %3) - br label %__barray_check_bounds.exit284.i + br label %__barray_check_bounds.exit283.i mask_block_err.i.i.i.i: ; preds = %mask_block_ok.i.i.i.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -56: ; preds = %cond_exit_353.i.i, %__barray_mask_return.exit281.i - %"303_0.sroa.15.0.i297.i" = phi i64 [ 0, %__barray_mask_return.exit281.i ], [ %57, %cond_exit_353.i.i ] - %57 = add nuw nsw i64 %"303_0.sroa.15.0.i297.i", 1 - %58 = lshr i64 %"303_0.sroa.15.0.i297.i", 6 +56: ; preds = %cond_exit_353.i.i, %__barray_mask_return.exit280.i + %"303_0.sroa.15.0.i296.i" = phi i64 [ 0, %__barray_mask_return.exit280.i ], [ %57, %cond_exit_353.i.i ] + %57 = add nuw nsw i64 %"303_0.sroa.15.0.i296.i", 1 + %58 = lshr i64 %"303_0.sroa.15.0.i296.i", 6 %59 = getelementptr inbounds i64, i64* %4, i64 %58 %60 = load i64, i64* %59, align 4 - %61 = shl nuw nsw i64 1, %"303_0.sroa.15.0.i297.i" + %61 = shl nuw nsw i64 1, %"303_0.sroa.15.0.i296.i" %62 = and i64 %60, %61 %.not.i99.i.i.i = icmp eq i64 %62, 0 br i1 %.not.i99.i.i.i, label %__barray_check_bounds.exit.i.i, label %panic.i.i.i.i @@ -236,7 +236,7 @@ panic.i.i.i.i: ; preds = %56 __barray_check_bounds.exit.i.i: ; preds = %56 %63 = xor i64 %60, %61 store i64 %63, i64* %59, align 4 - %64 = getelementptr inbounds i64, i64* %2, i64 %"303_0.sroa.15.0.i297.i" + %64 = getelementptr inbounds i64, i64* %2, i64 %"303_0.sroa.15.0.i296.i" %65 = load i64, i64* %64, align 4 %lazy_measure.i.i = tail call i64 @___lazy_measure(i64 %65) tail call void @___qfree(i64 %65) @@ -254,51 +254,51 @@ cond_exit_353.i.i: ; preds = %__barray_check_boun %"367_054.fca.1.insert.i.i" = insertvalue { i1, i64, i1 } { i1 true, i64 poison, i1 poison }, i64 %lazy_measure.i.i, 1 %69 = xor i64 %67, %61 store i64 %69, i64* %66, align 4 - %70 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"303_0.sroa.15.0.i297.i" + %70 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"303_0.sroa.15.0.i296.i" store { i1, i64, i1 } %"367_054.fca.1.insert.i.i", { i1, i64, i1 }* %70, align 4 - %exitcond298.not.i = icmp eq i64 %57, 10 - br i1 %exitcond298.not.i, label %mask_block_ok.i.i.i.i, label %56 + %exitcond297.not.i = icmp eq i64 %57, 10 + br i1 %exitcond297.not.i, label %mask_block_ok.i.i.i.i, label %56 -cond_160_case_0.i: ; preds = %cond_exit_160.i +cond_187_case_0.i: ; preds = %cond_exit_187.i %71 = load i64, i64* %52, align 4 %72 = or i64 %71, -1024 store i64 %72, i64* %52, align 4 %73 = icmp eq i64 %72, -1 br i1 %73, label %__hugr__.main.1.exit, label %mask_block_err.i.i -mask_block_err.i.i: ; preds = %cond_160_case_0.i +mask_block_err.i.i: ; preds = %cond_187_case_0.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit284.i: ; preds = %"__hugr__.$measure_array$$n(10).277.exit.i", %cond_exit_160.i - %"162_0.0.i1" = phi i64 [ 0, %"__hugr__.$measure_array$$n(10).277.exit.i" ], [ %82, %cond_exit_160.i ] - %74 = lshr i64 %"162_0.0.i1", 6 +__barray_check_bounds.exit283.i: ; preds = %"__hugr__.$measure_array$$n(10).277.exit.i", %cond_exit_187.i + %"164_0.0.i1" = phi i64 [ 0, %"__hugr__.$measure_array$$n(10).277.exit.i" ], [ %82, %cond_exit_187.i ] + %74 = lshr i64 %"164_0.0.i1", 6 %75 = getelementptr inbounds i64, i64* %52, i64 %74 %76 = load i64, i64* %75, align 4 - %77 = shl nuw nsw i64 1, %"162_0.0.i1" + %77 = shl nuw nsw i64 1, %"164_0.0.i1" %78 = and i64 %76, %77 %.not.i = icmp eq i64 %78, 0 - br i1 %.not.i, label %__barray_mask_borrow.exit289.i, label %cond_exit_160.i + br i1 %.not.i, label %__barray_mask_borrow.exit288.i, label %cond_exit_187.i -__barray_mask_borrow.exit289.i: ; preds = %__barray_check_bounds.exit284.i +__barray_mask_borrow.exit288.i: ; preds = %__barray_check_bounds.exit283.i %79 = xor i64 %76, %77 store i64 %79, i64* %75, align 4 - %80 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"162_0.0.i1" + %80 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %50, i64 %"164_0.0.i1" %81 = load { i1, i64, i1 }, { i1, i64, i1 }* %80, align 4 - %.fca.0.extract180.i = extractvalue { i1, i64, i1 } %81, 0 - br i1 %.fca.0.extract180.i, label %cond_85_case_1.i, label %cond_exit_160.i + %.fca.0.extract179.i = extractvalue { i1, i64, i1 } %81, 0 + br i1 %.fca.0.extract179.i, label %cond_87_case_1.i, label %cond_exit_187.i -cond_exit_160.i: ; preds = %cond_85_case_1.i, %__barray_mask_borrow.exit289.i, %__barray_check_bounds.exit284.i - %82 = add nuw nsw i64 %"162_0.0.i1", 1 +cond_exit_187.i: ; preds = %cond_87_case_1.i, %__barray_mask_borrow.exit288.i, %__barray_check_bounds.exit283.i + %82 = add nuw nsw i64 %"164_0.0.i1", 1 %exitcond.not = icmp eq i64 %82, 10 - br i1 %exitcond.not, label %cond_160_case_0.i, label %__barray_check_bounds.exit284.i + br i1 %exitcond.not, label %cond_187_case_0.i, label %__barray_check_bounds.exit283.i -cond_85_case_1.i: ; preds = %__barray_mask_borrow.exit289.i +cond_87_case_1.i: ; preds = %__barray_mask_borrow.exit288.i %.fca.1.extract.i = extractvalue { i1, i64, i1 } %81, 1 tail call void @___dec_future_refcount(i64 %.fca.1.extract.i) - br label %cond_exit_160.i + br label %cond_exit_187.i -__hugr__.main.1.exit: ; preds = %cond_160_case_0.i +__hugr__.main.1.exit: ; preds = %cond_187_case_0.i tail call void @heap_free(i8* %49) tail call void @heap_free(i8* nonnull %51) %83 = tail call i64 @teardown() diff --git a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-windows-msvc-print_array/print_array_x86_64-windows-msvc b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-windows-msvc-print_array/print_array_x86_64-windows-msvc index c85dce449..61d861f1a 100644 --- a/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-windows-msvc-print_array/print_array_x86_64-windows-msvc +++ b/qis-compiler/python/tests/snapshots/test_basic_generation/test_llvm/x86_64-windows-msvc-print_array/print_array_x86_64-windows-msvc @@ -34,8 +34,8 @@ alloca_block: br label %cond_20_case_1 cond_20_case_1: ; preds = %alloca_block, %cond_exit_20 - %"15_0.sroa.0.0961" = phi i64 [ 0, %alloca_block ], [ %12, %cond_exit_20 ] - %12 = add nuw nsw i64 %"15_0.sroa.0.0961", 1 + %"15_0.sroa.0.0955" = phi i64 [ 0, %alloca_block ], [ %12, %cond_exit_20 ] + %12 = add nuw nsw i64 %"15_0.sroa.0.0955", 1 %qalloc.i = tail call i64 @___qalloc() %not_max.not.i = icmp eq i64 %qalloc.i, -1 br i1 %not_max.not.i, label %id_bb.i, label %reset_bb.i @@ -55,10 +55,10 @@ cond_303_case_0.i: ; preds = %id_bb.i unreachable __barray_check_bounds.exit: ; preds = %id_bb.i - %15 = lshr i64 %"15_0.sroa.0.0961", 6 + %15 = lshr i64 %"15_0.sroa.0.0955", 6 %16 = getelementptr inbounds i64, i64* %11, i64 %15 %17 = load i64, i64* %16, align 4 - %18 = shl nuw nsw i64 1, %"15_0.sroa.0.0961" + %18 = shl nuw nsw i64 1, %"15_0.sroa.0.0955" %19 = and i64 %17, %18 %.not.i = icmp eq i64 %19, 0 br i1 %.not.i, label %panic.i, label %cond_exit_20 @@ -71,7 +71,7 @@ cond_exit_20: ; preds = %__barray_check_boun %.fca.1.extract.i = extractvalue { i1, i64 } %14, 1 %20 = xor i64 %17, %18 store i64 %20, i64* %16, align 4 - %21 = getelementptr inbounds i64, i64* %9, i64 %"15_0.sroa.0.0961" + %21 = getelementptr inbounds i64, i64* %9, i64 %"15_0.sroa.0.0955" store i64 %.fca.1.extract.i, i64* %21, align 4 %exitcond.not = icmp eq i64 %12, 10 br i1 %exitcond.not, label %loop_out, label %cond_20_case_1 @@ -79,10 +79,10 @@ cond_exit_20: ; preds = %__barray_check_boun loop_out: ; preds = %cond_exit_20 %22 = load i64, i64* %11, align 4 %23 = and i64 %22, 1 - %.not.i852 = icmp eq i64 %23, 0 - br i1 %.not.i852, label %__barray_mask_borrow.exit, label %panic.i853 + %.not.i846 = icmp eq i64 %23, 0 + br i1 %.not.i846, label %__barray_mask_borrow.exit, label %panic.i847 -panic.i853: ; preds = %loop_out +panic.i847: ; preds = %loop_out tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable @@ -93,27 +93,27 @@ __barray_mask_borrow.exit: ; preds = %loop_out tail call void @___rxy(i64 %25, double 0x400921FB54442D18, double 0.000000e+00) %26 = load i64, i64* %11, align 4 %27 = and i64 %26, 1 - %.not.i854 = icmp eq i64 %27, 0 - br i1 %.not.i854, label %panic.i855, label %__barray_mask_return.exit856 + %.not.i848 = icmp eq i64 %27, 0 + br i1 %.not.i848, label %panic.i849, label %__barray_mask_return.exit850 -panic.i855: ; preds = %__barray_mask_borrow.exit +panic.i849: ; preds = %__barray_mask_borrow.exit tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit856: ; preds = %__barray_mask_borrow.exit +__barray_mask_return.exit850: ; preds = %__barray_mask_borrow.exit %28 = xor i64 %26, 1 store i64 %28, i64* %11, align 4 store i64 %25, i64* %9, align 4 %29 = load i64, i64* %11, align 4 %30 = and i64 %29, 4 - %.not.i857 = icmp eq i64 %30, 0 - br i1 %.not.i857, label %__barray_mask_borrow.exit859, label %panic.i858 + %.not.i851 = icmp eq i64 %30, 0 + br i1 %.not.i851, label %__barray_mask_borrow.exit853, label %panic.i852 -panic.i858: ; preds = %__barray_mask_return.exit856 +panic.i852: ; preds = %__barray_mask_return.exit850 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit859: ; preds = %__barray_mask_return.exit856 +__barray_mask_borrow.exit853: ; preds = %__barray_mask_return.exit850 %31 = xor i64 %29, 4 store i64 %31, i64* %11, align 4 %32 = getelementptr inbounds i8, i8* %8, i64 16 @@ -122,27 +122,27 @@ __barray_mask_borrow.exit859: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %34, double 0x400921FB54442D18, double 0.000000e+00) %35 = load i64, i64* %11, align 4 %36 = and i64 %35, 4 - %.not.i860 = icmp eq i64 %36, 0 - br i1 %.not.i860, label %panic.i861, label %__barray_mask_return.exit862 + %.not.i854 = icmp eq i64 %36, 0 + br i1 %.not.i854, label %panic.i855, label %__barray_mask_return.exit856 -panic.i861: ; preds = %__barray_mask_borrow.exit859 +panic.i855: ; preds = %__barray_mask_borrow.exit853 tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit862: ; preds = %__barray_mask_borrow.exit859 +__barray_mask_return.exit856: ; preds = %__barray_mask_borrow.exit853 %37 = xor i64 %35, 4 store i64 %37, i64* %11, align 4 store i64 %34, i64* %33, align 4 %38 = load i64, i64* %11, align 4 %39 = and i64 %38, 8 - %.not.i863 = icmp eq i64 %39, 0 - br i1 %.not.i863, label %__barray_mask_borrow.exit865, label %panic.i864 + %.not.i857 = icmp eq i64 %39, 0 + br i1 %.not.i857, label %__barray_mask_borrow.exit859, label %panic.i858 -panic.i864: ; preds = %__barray_mask_return.exit862 +panic.i858: ; preds = %__barray_mask_return.exit856 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit865: ; preds = %__barray_mask_return.exit862 +__barray_mask_borrow.exit859: ; preds = %__barray_mask_return.exit856 %40 = xor i64 %38, 8 store i64 %40, i64* %11, align 4 %41 = getelementptr inbounds i8, i8* %8, i64 24 @@ -151,27 +151,27 @@ __barray_mask_borrow.exit865: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %43, double 0x400921FB54442D18, double 0.000000e+00) %44 = load i64, i64* %11, align 4 %45 = and i64 %44, 8 - %.not.i866 = icmp eq i64 %45, 0 - br i1 %.not.i866, label %panic.i867, label %__barray_mask_return.exit868 + %.not.i860 = icmp eq i64 %45, 0 + br i1 %.not.i860, label %panic.i861, label %__barray_mask_return.exit862 -panic.i867: ; preds = %__barray_mask_borrow.exit865 +panic.i861: ; preds = %__barray_mask_borrow.exit859 tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit868: ; preds = %__barray_mask_borrow.exit865 +__barray_mask_return.exit862: ; preds = %__barray_mask_borrow.exit859 %46 = xor i64 %44, 8 store i64 %46, i64* %11, align 4 store i64 %43, i64* %42, align 4 %47 = load i64, i64* %11, align 4 %48 = and i64 %47, 512 - %.not.i869 = icmp eq i64 %48, 0 - br i1 %.not.i869, label %__barray_mask_borrow.exit871, label %panic.i870 + %.not.i863 = icmp eq i64 %48, 0 + br i1 %.not.i863, label %__barray_mask_borrow.exit865, label %panic.i864 -panic.i870: ; preds = %__barray_mask_return.exit868 +panic.i864: ; preds = %__barray_mask_return.exit862 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -__barray_mask_borrow.exit871: ; preds = %__barray_mask_return.exit868 +__barray_mask_borrow.exit865: ; preds = %__barray_mask_return.exit862 %49 = xor i64 %47, 512 store i64 %49, i64* %11, align 4 %50 = getelementptr inbounds i8, i8* %8, i64 72 @@ -180,14 +180,14 @@ __barray_mask_borrow.exit871: ; preds = %__barray_mask_retur tail call void @___rxy(i64 %52, double 0x400921FB54442D18, double 0.000000e+00) %53 = load i64, i64* %11, align 4 %54 = and i64 %53, 512 - %.not.i872 = icmp eq i64 %54, 0 - br i1 %.not.i872, label %panic.i873, label %__barray_mask_return.exit874 + %.not.i866 = icmp eq i64 %54, 0 + br i1 %.not.i866, label %panic.i867, label %__barray_mask_return.exit868 -panic.i873: ; preds = %__barray_mask_borrow.exit871 +panic.i867: ; preds = %__barray_mask_borrow.exit865 tail call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -__barray_mask_return.exit874: ; preds = %__barray_mask_borrow.exit871 +__barray_mask_return.exit868: ; preds = %__barray_mask_borrow.exit865 %55 = xor i64 %53, 512 store i64 %55, i64* %11, align 4 store i64 %52, i64* %51, align 4 @@ -223,13 +223,13 @@ mask_block_err.i.i.i: ; preds = %mask_block_ok.i.i.i tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -69: ; preds = %__barray_mask_return.exit874, %cond_exit_443.i - %"393_0.sroa.15.0.i963" = phi i64 [ 0, %__barray_mask_return.exit874 ], [ %70, %cond_exit_443.i ] - %70 = add nuw nsw i64 %"393_0.sroa.15.0.i963", 1 - %71 = lshr i64 %"393_0.sroa.15.0.i963", 6 +69: ; preds = %__barray_mask_return.exit868, %cond_exit_443.i + %"393_0.sroa.15.0.i957" = phi i64 [ 0, %__barray_mask_return.exit868 ], [ %70, %cond_exit_443.i ] + %70 = add nuw nsw i64 %"393_0.sroa.15.0.i957", 1 + %71 = lshr i64 %"393_0.sroa.15.0.i957", 6 %72 = getelementptr inbounds i64, i64* %11, i64 %71 %73 = load i64, i64* %72, align 4 - %74 = shl nuw nsw i64 1, %"393_0.sroa.15.0.i963" + %74 = shl nuw nsw i64 1, %"393_0.sroa.15.0.i957" %75 = and i64 %73, %74 %.not.i99.i.i = icmp eq i64 %75, 0 br i1 %.not.i99.i.i, label %__barray_check_bounds.exit.i, label %panic.i.i.i @@ -241,7 +241,7 @@ panic.i.i.i: ; preds = %69 __barray_check_bounds.exit.i: ; preds = %69 %76 = xor i64 %73, %74 store i64 %76, i64* %72, align 4 - %77 = getelementptr inbounds i64, i64* %9, i64 %"393_0.sroa.15.0.i963" + %77 = getelementptr inbounds i64, i64* %9, i64 %"393_0.sroa.15.0.i957" %78 = load i64, i64* %77, align 4 %lazy_measure.i = tail call i64 @___lazy_measure(i64 %78) tail call void @___qfree(i64 %78) @@ -259,10 +259,10 @@ cond_exit_443.i: ; preds = %__barray_check_boun %"457_054.fca.1.insert.i" = insertvalue { i1, i64, i1 } { i1 true, i64 poison, i1 poison }, i64 %lazy_measure.i, 1 %82 = xor i64 %80, %74 store i64 %82, i64* %79, align 4 - %83 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %"393_0.sroa.15.0.i963" + %83 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %"393_0.sroa.15.0.i957" store { i1, i64, i1 } %"457_054.fca.1.insert.i", { i1, i64, i1 }* %83, align 4 - %exitcond979.not = icmp eq i64 %70, 10 - br i1 %exitcond979.not, label %mask_block_ok.i.i.i, label %69 + %exitcond973.not = icmp eq i64 %70, 10 + br i1 %exitcond973.not, label %mask_block_ok.i.i.i, label %69 __barray_check_none_borrowed.exit: ; preds = %"__hugr__.$measure_array$$n(10).367.exit" %84 = tail call i8* @heap_alloc(i64 240) @@ -277,78 +277,78 @@ mask_block_err.i: ; preds = %"__hugr__.$measure_ tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -89: ; preds = %__barray_check_none_borrowed.exit, %__hugr__.const_fun_290.309.exit - %storemerge850968 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %107, %__hugr__.const_fun_290.309.exit ] - %90 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %105, %__hugr__.const_fun_290.309.exit ] - %91 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %storemerge850968 +89: ; preds = %__barray_check_none_borrowed.exit, %__hugr__.const_fun_338.322.exit + %storemerge844962 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %107, %__hugr__.const_fun_338.322.exit ] + %90 = phi i64 [ 0, %__barray_check_none_borrowed.exit ], [ %105, %__hugr__.const_fun_338.322.exit ] + %91 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %57, i64 %storemerge844962 %92 = load { i1, i64, i1 }, { i1, i64, i1 }* %91, align 4 %.fca.0.extract118.i = extractvalue { i1, i64, i1 } %92, 0 %.fca.1.extract119.i = extractvalue { i1, i64, i1 } %92, 1 - br i1 %.fca.0.extract118.i, label %cond_525_case_1.i, label %cond_exit_525.i + br i1 %.fca.0.extract118.i, label %cond_513_case_1.i, label %cond_exit_513.i -cond_525_case_1.i: ; preds = %89 +cond_513_case_1.i: ; preds = %89 tail call void @___inc_future_refcount(i64 %.fca.1.extract119.i) %93 = insertvalue { i1, i64, i1 } { i1 true, i64 poison, i1 poison }, i64 %.fca.1.extract119.i, 1 - br label %cond_exit_525.i + br label %cond_exit_513.i -cond_exit_525.i: ; preds = %cond_525_case_1.i, %89 - %.pn.i = phi { i1, i64, i1 } [ %93, %cond_525_case_1.i ], [ %92, %89 ] +cond_exit_513.i: ; preds = %cond_513_case_1.i, %89 + %.pn.i = phi { i1, i64, i1 } [ %93, %cond_513_case_1.i ], [ %92, %89 ] %"04.sroa.6.0.i" = extractvalue { i1, i64, i1 } %.pn.i, 2 %94 = icmp ult i64 %90, 10 - br i1 %94, label %95, label %cond_528_case_0.i + br i1 %94, label %95, label %cond_516_case_0.i -95: ; preds = %cond_exit_525.i +95: ; preds = %cond_exit_513.i %96 = lshr i64 %90, 6 %97 = getelementptr inbounds i64, i64* %65, i64 %96 %98 = load i64, i64* %97, align 4 %99 = shl nuw nsw i64 1, %90 %100 = and i64 %98, %99 - %.not.i.i876 = icmp eq i64 %100, 0 - br i1 %.not.i.i876, label %cond_528_case_1.i, label %panic.i.i877 + %.not.i.i870 = icmp eq i64 %100, 0 + br i1 %.not.i.i870, label %cond_516_case_1.i, label %panic.i.i871 -panic.i.i877: ; preds = %95 +panic.i.i871: ; preds = %95 tail call void @panic(i32 1002, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @"e_Array elem.E746B1A3.0", i64 0, i64 0)) unreachable -cond_528_case_0.i: ; preds = %cond_exit_525.i +cond_516_case_0.i: ; preds = %cond_exit_513.i tail call void @panic(i32 1001, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @"e_Expected v.E6312129.0", i64 0, i64 0)) unreachable -cond_528_case_1.i: ; preds = %95 +cond_516_case_1.i: ; preds = %95 %"17.fca.2.insert.i" = insertvalue { i1, i64, i1 } %92, i1 %"04.sroa.6.0.i", 2 %101 = insertvalue { i1, { i1, i64, i1 } } { i1 true, { i1, i64, i1 } poison }, { i1, i64, i1 } %"17.fca.2.insert.i", 1 %102 = getelementptr inbounds { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %88, i64 %90 %103 = getelementptr inbounds { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %102, i64 0, i32 0 %104 = load i1, i1* %103, align 1 store { i1, { i1, i64, i1 } } %101, { i1, { i1, i64, i1 } }* %102, align 4 - br i1 %104, label %cond_529_case_1.i, label %__hugr__.const_fun_290.309.exit + br i1 %104, label %cond_517_case_1.i, label %__hugr__.const_fun_338.322.exit -cond_529_case_1.i: ; preds = %cond_528_case_1.i +cond_517_case_1.i: ; preds = %cond_516_case_1.i tail call void @panic(i32 1001, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @"e_Expected v.2F17E0A9.0", i64 0, i64 0)) unreachable -__hugr__.const_fun_290.309.exit: ; preds = %cond_528_case_1.i +__hugr__.const_fun_338.322.exit: ; preds = %cond_516_case_1.i %105 = add nuw nsw i64 %90, 1 - %106 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %85, i64 %storemerge850968 + %106 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %85, i64 %storemerge844962 store { i1, i64, i1 } %"17.fca.2.insert.i", { i1, i64, i1 }* %106, align 4 - %107 = add nuw nsw i64 %storemerge850968, 1 - %exitcond980.not = icmp eq i64 %107, 10 - br i1 %exitcond980.not, label %mask_block_ok.i881, label %89 + %107 = add nuw nsw i64 %storemerge844962, 1 + %exitcond974.not = icmp eq i64 %107, 10 + br i1 %exitcond974.not, label %mask_block_ok.i875, label %89 -mask_block_ok.i881: ; preds = %__hugr__.const_fun_290.309.exit +mask_block_ok.i875: ; preds = %__hugr__.const_fun_338.322.exit tail call void @heap_free(i8* nonnull %56) tail call void @heap_free(i8* %58) %108 = load i64, i64* %65, align 4 %109 = and i64 %108, 1023 store i64 %109, i64* %65, align 4 %110 = icmp eq i64 %109, 0 - br i1 %110, label %__barray_check_none_borrowed.exit883, label %mask_block_err.i882 + br i1 %110, label %__barray_check_none_borrowed.exit877, label %mask_block_err.i876 -mask_block_err.i882: ; preds = %mask_block_ok.i881 +mask_block_err.i876: ; preds = %mask_block_ok.i875 tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_none_borrowed.exit883: ; preds = %mask_block_ok.i881 +__barray_check_none_borrowed.exit877: ; preds = %mask_block_ok.i875 %111 = tail call i8* @heap_alloc(i64 240) %112 = bitcast i8* %111 to { i1, i64, i1 }* %113 = tail call i8* @heap_alloc(i64 8) @@ -356,22 +356,22 @@ __barray_check_none_borrowed.exit883: ; preds = %mask_block_ok.i881 store i64 0, i64* %114, align 1 %115 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %88, align 4 %.fca.0.extract11.i = extractvalue { i1, { i1, i64, i1 } } %115, 0 - br i1 %.fca.0.extract11.i, label %__hugr__.const_fun_284.290.exit, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i, label %__hugr__.const_fun_287.338.exit, label %cond_558_case_0.i -cond_570_case_0.i: ; preds = %__hugr__.const_fun_284.290.exit.8, %__hugr__.const_fun_284.290.exit.7, %__hugr__.const_fun_284.290.exit.6, %__hugr__.const_fun_284.290.exit.5, %__hugr__.const_fun_284.290.exit.4, %__hugr__.const_fun_284.290.exit.3, %__hugr__.const_fun_284.290.exit.2, %__hugr__.const_fun_284.290.exit.1, %__hugr__.const_fun_284.290.exit, %__barray_check_none_borrowed.exit883 +cond_558_case_0.i: ; preds = %__hugr__.const_fun_287.338.exit.8, %__hugr__.const_fun_287.338.exit.7, %__hugr__.const_fun_287.338.exit.6, %__hugr__.const_fun_287.338.exit.5, %__hugr__.const_fun_287.338.exit.4, %__hugr__.const_fun_287.338.exit.3, %__hugr__.const_fun_287.338.exit.2, %__hugr__.const_fun_287.338.exit.1, %__hugr__.const_fun_287.338.exit, %__barray_check_none_borrowed.exit877 tail call void @panic(i32 1001, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @"e_Expected v.E6312129.0", i64 0, i64 0)) unreachable -__hugr__.const_fun_284.290.exit: ; preds = %__barray_check_none_borrowed.exit883 +__hugr__.const_fun_287.338.exit: ; preds = %__barray_check_none_borrowed.exit877 %116 = extractvalue { i1, { i1, i64, i1 } } %115, 1 store { i1, i64, i1 } %116, { i1, i64, i1 }* %112, align 4 %117 = getelementptr inbounds i8, i8* %63, i64 32 %118 = bitcast i8* %117 to { i1, { i1, i64, i1 } }* %119 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %118, align 4 %.fca.0.extract11.i.1 = extractvalue { i1, { i1, i64, i1 } } %119, 0 - br i1 %.fca.0.extract11.i.1, label %__hugr__.const_fun_284.290.exit.1, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.1, label %__hugr__.const_fun_287.338.exit.1, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.1: ; preds = %__hugr__.const_fun_284.290.exit +__hugr__.const_fun_287.338.exit.1: ; preds = %__hugr__.const_fun_287.338.exit %120 = extractvalue { i1, { i1, i64, i1 } } %119, 1 %121 = getelementptr inbounds i8, i8* %111, i64 24 %122 = bitcast i8* %121 to { i1, i64, i1 }* @@ -380,9 +380,9 @@ __hugr__.const_fun_284.290.exit.1: ; preds = %__hugr__.const_fun_ %124 = bitcast i8* %123 to { i1, { i1, i64, i1 } }* %125 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %124, align 4 %.fca.0.extract11.i.2 = extractvalue { i1, { i1, i64, i1 } } %125, 0 - br i1 %.fca.0.extract11.i.2, label %__hugr__.const_fun_284.290.exit.2, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.2, label %__hugr__.const_fun_287.338.exit.2, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.2: ; preds = %__hugr__.const_fun_284.290.exit.1 +__hugr__.const_fun_287.338.exit.2: ; preds = %__hugr__.const_fun_287.338.exit.1 %126 = extractvalue { i1, { i1, i64, i1 } } %125, 1 %127 = getelementptr inbounds i8, i8* %111, i64 48 %128 = bitcast i8* %127 to { i1, i64, i1 }* @@ -391,9 +391,9 @@ __hugr__.const_fun_284.290.exit.2: ; preds = %__hugr__.const_fun_ %130 = bitcast i8* %129 to { i1, { i1, i64, i1 } }* %131 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %130, align 4 %.fca.0.extract11.i.3 = extractvalue { i1, { i1, i64, i1 } } %131, 0 - br i1 %.fca.0.extract11.i.3, label %__hugr__.const_fun_284.290.exit.3, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.3, label %__hugr__.const_fun_287.338.exit.3, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.3: ; preds = %__hugr__.const_fun_284.290.exit.2 +__hugr__.const_fun_287.338.exit.3: ; preds = %__hugr__.const_fun_287.338.exit.2 %132 = extractvalue { i1, { i1, i64, i1 } } %131, 1 %133 = getelementptr inbounds i8, i8* %111, i64 72 %134 = bitcast i8* %133 to { i1, i64, i1 }* @@ -402,9 +402,9 @@ __hugr__.const_fun_284.290.exit.3: ; preds = %__hugr__.const_fun_ %136 = bitcast i8* %135 to { i1, { i1, i64, i1 } }* %137 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %136, align 4 %.fca.0.extract11.i.4 = extractvalue { i1, { i1, i64, i1 } } %137, 0 - br i1 %.fca.0.extract11.i.4, label %__hugr__.const_fun_284.290.exit.4, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.4, label %__hugr__.const_fun_287.338.exit.4, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.4: ; preds = %__hugr__.const_fun_284.290.exit.3 +__hugr__.const_fun_287.338.exit.4: ; preds = %__hugr__.const_fun_287.338.exit.3 %138 = extractvalue { i1, { i1, i64, i1 } } %137, 1 %139 = getelementptr inbounds i8, i8* %111, i64 96 %140 = bitcast i8* %139 to { i1, i64, i1 }* @@ -413,9 +413,9 @@ __hugr__.const_fun_284.290.exit.4: ; preds = %__hugr__.const_fun_ %142 = bitcast i8* %141 to { i1, { i1, i64, i1 } }* %143 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %142, align 4 %.fca.0.extract11.i.5 = extractvalue { i1, { i1, i64, i1 } } %143, 0 - br i1 %.fca.0.extract11.i.5, label %__hugr__.const_fun_284.290.exit.5, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.5, label %__hugr__.const_fun_287.338.exit.5, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.5: ; preds = %__hugr__.const_fun_284.290.exit.4 +__hugr__.const_fun_287.338.exit.5: ; preds = %__hugr__.const_fun_287.338.exit.4 %144 = extractvalue { i1, { i1, i64, i1 } } %143, 1 %145 = getelementptr inbounds i8, i8* %111, i64 120 %146 = bitcast i8* %145 to { i1, i64, i1 }* @@ -424,9 +424,9 @@ __hugr__.const_fun_284.290.exit.5: ; preds = %__hugr__.const_fun_ %148 = bitcast i8* %147 to { i1, { i1, i64, i1 } }* %149 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %148, align 4 %.fca.0.extract11.i.6 = extractvalue { i1, { i1, i64, i1 } } %149, 0 - br i1 %.fca.0.extract11.i.6, label %__hugr__.const_fun_284.290.exit.6, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.6, label %__hugr__.const_fun_287.338.exit.6, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.6: ; preds = %__hugr__.const_fun_284.290.exit.5 +__hugr__.const_fun_287.338.exit.6: ; preds = %__hugr__.const_fun_287.338.exit.5 %150 = extractvalue { i1, { i1, i64, i1 } } %149, 1 %151 = getelementptr inbounds i8, i8* %111, i64 144 %152 = bitcast i8* %151 to { i1, i64, i1 }* @@ -435,9 +435,9 @@ __hugr__.const_fun_284.290.exit.6: ; preds = %__hugr__.const_fun_ %154 = bitcast i8* %153 to { i1, { i1, i64, i1 } }* %155 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %154, align 4 %.fca.0.extract11.i.7 = extractvalue { i1, { i1, i64, i1 } } %155, 0 - br i1 %.fca.0.extract11.i.7, label %__hugr__.const_fun_284.290.exit.7, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.7, label %__hugr__.const_fun_287.338.exit.7, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.7: ; preds = %__hugr__.const_fun_284.290.exit.6 +__hugr__.const_fun_287.338.exit.7: ; preds = %__hugr__.const_fun_287.338.exit.6 %156 = extractvalue { i1, { i1, i64, i1 } } %155, 1 %157 = getelementptr inbounds i8, i8* %111, i64 168 %158 = bitcast i8* %157 to { i1, i64, i1 }* @@ -446,9 +446,9 @@ __hugr__.const_fun_284.290.exit.7: ; preds = %__hugr__.const_fun_ %160 = bitcast i8* %159 to { i1, { i1, i64, i1 } }* %161 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %160, align 4 %.fca.0.extract11.i.8 = extractvalue { i1, { i1, i64, i1 } } %161, 0 - br i1 %.fca.0.extract11.i.8, label %__hugr__.const_fun_284.290.exit.8, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.8, label %__hugr__.const_fun_287.338.exit.8, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.8: ; preds = %__hugr__.const_fun_284.290.exit.7 +__hugr__.const_fun_287.338.exit.8: ; preds = %__hugr__.const_fun_287.338.exit.7 %162 = extractvalue { i1, { i1, i64, i1 } } %161, 1 %163 = getelementptr inbounds i8, i8* %111, i64 192 %164 = bitcast i8* %163 to { i1, i64, i1 }* @@ -457,86 +457,86 @@ __hugr__.const_fun_284.290.exit.8: ; preds = %__hugr__.const_fun_ %166 = bitcast i8* %165 to { i1, { i1, i64, i1 } }* %167 = load { i1, { i1, i64, i1 } }, { i1, { i1, i64, i1 } }* %166, align 4 %.fca.0.extract11.i.9 = extractvalue { i1, { i1, i64, i1 } } %167, 0 - br i1 %.fca.0.extract11.i.9, label %__hugr__.const_fun_284.290.exit.9, label %cond_570_case_0.i + br i1 %.fca.0.extract11.i.9, label %__hugr__.const_fun_287.338.exit.9, label %cond_558_case_0.i -__hugr__.const_fun_284.290.exit.9: ; preds = %__hugr__.const_fun_284.290.exit.8 +__hugr__.const_fun_287.338.exit.9: ; preds = %__hugr__.const_fun_287.338.exit.8 %168 = extractvalue { i1, { i1, i64, i1 } } %167, 1 %169 = getelementptr inbounds i8, i8* %111, i64 216 %170 = bitcast i8* %169 to { i1, i64, i1 }* store { i1, i64, i1 } %168, { i1, i64, i1 }* %170, align 4 tail call void @heap_free(i8* nonnull %63) tail call void @heap_free(i8* nonnull %64) - br label %__barray_check_bounds.exit888 + br label %__barray_check_bounds.exit882 -cond_165_case_0: ; preds = %cond_exit_165 +cond_169_case_0: ; preds = %cond_exit_169 %171 = load i64, i64* %114, align 4 %172 = or i64 %171, -1024 store i64 %172, i64* %114, align 4 %173 = icmp eq i64 %172, -1 - br i1 %173, label %loop_out139, label %mask_block_err.i886 + br i1 %173, label %loop_out135, label %mask_block_err.i880 -mask_block_err.i886: ; preds = %cond_165_case_0 +mask_block_err.i880: ; preds = %cond_169_case_0 tail call void @panic(i32 1002, i8* getelementptr inbounds ([70 x i8], [70 x i8]* @"e_Array cont.EFA5AC45.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit888: ; preds = %__hugr__.const_fun_284.290.exit.9, %cond_exit_165 - %"167_0.0989" = phi i64 [ 0, %__hugr__.const_fun_284.290.exit.9 ], [ %174, %cond_exit_165 ] - %174 = add nuw nsw i64 %"167_0.0989", 1 - %175 = lshr i64 %"167_0.0989", 6 +__barray_check_bounds.exit882: ; preds = %__hugr__.const_fun_287.338.exit.9, %cond_exit_169 + %"172_0.0983" = phi i64 [ 0, %__hugr__.const_fun_287.338.exit.9 ], [ %174, %cond_exit_169 ] + %174 = add nuw nsw i64 %"172_0.0983", 1 + %175 = lshr i64 %"172_0.0983", 6 %176 = getelementptr inbounds i64, i64* %114, i64 %175 %177 = load i64, i64* %176, align 4 - %178 = shl nuw nsw i64 1, %"167_0.0989" + %178 = shl nuw nsw i64 1, %"172_0.0983" %179 = and i64 %177, %178 %.not = icmp eq i64 %179, 0 - br i1 %.not, label %__barray_mask_borrow.exit893, label %cond_exit_165 + br i1 %.not, label %__barray_mask_borrow.exit887, label %cond_exit_169 -__barray_mask_borrow.exit893: ; preds = %__barray_check_bounds.exit888 +__barray_mask_borrow.exit887: ; preds = %__barray_check_bounds.exit882 %180 = xor i64 %177, %178 store i64 %180, i64* %176, align 4 - %181 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %112, i64 %"167_0.0989" + %181 = getelementptr inbounds { i1, i64, i1 }, { i1, i64, i1 }* %112, i64 %"172_0.0983" %182 = load { i1, i64, i1 }, { i1, i64, i1 }* %181, align 4 - %.fca.0.extract511 = extractvalue { i1, i64, i1 } %182, 0 - br i1 %.fca.0.extract511, label %cond_501_case_1, label %cond_exit_165 + %.fca.0.extract505 = extractvalue { i1, i64, i1 } %182, 0 + br i1 %.fca.0.extract505, label %cond_496_case_1, label %cond_exit_169 -cond_exit_165: ; preds = %cond_501_case_1, %__barray_mask_borrow.exit893, %__barray_check_bounds.exit888 - %183 = icmp ult i64 %"167_0.0989", 9 - br i1 %183, label %__barray_check_bounds.exit888, label %cond_165_case_0 +cond_exit_169: ; preds = %cond_496_case_1, %__barray_mask_borrow.exit887, %__barray_check_bounds.exit882 + %183 = icmp ult i64 %"172_0.0983", 9 + br i1 %183, label %__barray_check_bounds.exit882, label %cond_169_case_0 -loop_out139: ; preds = %cond_165_case_0 +loop_out135: ; preds = %cond_169_case_0 tail call void @heap_free(i8* %111) tail call void @heap_free(i8* nonnull %113) %184 = load i64, i64* %87, align 4 %185 = and i64 %184, 1023 store i64 %185, i64* %87, align 4 %186 = icmp eq i64 %185, 0 - br i1 %186, label %__barray_check_none_borrowed.exit898, label %mask_block_err.i897 + br i1 %186, label %__barray_check_none_borrowed.exit892, label %mask_block_err.i891 -__barray_check_none_borrowed.exit898: ; preds = %loop_out139 +__barray_check_none_borrowed.exit892: ; preds = %loop_out135 %187 = tail call i8* @heap_alloc(i64 10) %188 = tail call i8* @heap_alloc(i64 8) %189 = bitcast i8* %188 to i64* store i64 0, i64* %189, align 1 %190 = load { i1, i64, i1 }, { i1, i64, i1 }* %85, align 4 - %.fca.0.extract.i899 = extractvalue { i1, i64, i1 } %190, 0 - %.fca.1.extract.i900 = extractvalue { i1, i64, i1 } %190, 1 - br i1 %.fca.0.extract.i899, label %cond_300_case_1.i, label %cond_300_case_0.i + %.fca.0.extract.i893 = extractvalue { i1, i64, i1 } %190, 0 + %.fca.1.extract.i894 = extractvalue { i1, i64, i1 } %190, 1 + br i1 %.fca.0.extract.i893, label %cond_300_case_1.i, label %cond_300_case_0.i -mask_block_err.i897: ; preds = %loop_out139 +mask_block_err.i891: ; preds = %loop_out135 tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -cond_501_case_1: ; preds = %__barray_mask_borrow.exit893 - %.fca.1.extract512 = extractvalue { i1, i64, i1 } %182, 1 - tail call void @___dec_future_refcount(i64 %.fca.1.extract512) - br label %cond_exit_165 +cond_496_case_1: ; preds = %__barray_mask_borrow.exit887 + %.fca.1.extract506 = extractvalue { i1, i64, i1 } %182, 1 + tail call void @___dec_future_refcount(i64 %.fca.1.extract506) + br label %cond_exit_169 -cond_300_case_0.i: ; preds = %__barray_check_none_borrowed.exit898 +cond_300_case_0.i: ; preds = %__barray_check_none_borrowed.exit892 %.fca.2.extract.i = extractvalue { i1, i64, i1 } %190, 2 br label %__hugr__.array.__read_bool.3.271.exit -cond_300_case_1.i: ; preds = %__barray_check_none_borrowed.exit898 - %read_bool.i = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900) +cond_300_case_1.i: ; preds = %__barray_check_none_borrowed.exit892 + %read_bool.i = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894) br label %__hugr__.array.__read_bool.3.271.exit __hugr__.array.__read_bool.3.271.exit: ; preds = %cond_300_case_0.i, %cond_300_case_1.i @@ -546,17 +546,17 @@ __hugr__.array.__read_bool.3.271.exit: ; preds = %cond_300_case_0.i, %192 = getelementptr inbounds i8, i8* %84, i64 24 %193 = bitcast i8* %192 to { i1, i64, i1 }* %194 = load { i1, i64, i1 }, { i1, i64, i1 }* %193, align 4 - %.fca.0.extract.i899.1 = extractvalue { i1, i64, i1 } %194, 0 - %.fca.1.extract.i900.1 = extractvalue { i1, i64, i1 } %194, 1 - br i1 %.fca.0.extract.i899.1, label %cond_300_case_1.i.1, label %cond_300_case_0.i.1 + %.fca.0.extract.i893.1 = extractvalue { i1, i64, i1 } %194, 0 + %.fca.1.extract.i894.1 = extractvalue { i1, i64, i1 } %194, 1 + br i1 %.fca.0.extract.i893.1, label %cond_300_case_1.i.1, label %cond_300_case_0.i.1 cond_300_case_0.i.1: ; preds = %__hugr__.array.__read_bool.3.271.exit %.fca.2.extract.i.1 = extractvalue { i1, i64, i1 } %194, 2 br label %__hugr__.array.__read_bool.3.271.exit.1 cond_300_case_1.i.1: ; preds = %__hugr__.array.__read_bool.3.271.exit - %read_bool.i.1 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.1) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.1) + %read_bool.i.1 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.1) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.1) br label %__hugr__.array.__read_bool.3.271.exit.1 __hugr__.array.__read_bool.3.271.exit.1: ; preds = %cond_300_case_1.i.1, %cond_300_case_0.i.1 @@ -567,17 +567,17 @@ __hugr__.array.__read_bool.3.271.exit.1: ; preds = %cond_300_case_1.i.1 %197 = getelementptr inbounds i8, i8* %84, i64 48 %198 = bitcast i8* %197 to { i1, i64, i1 }* %199 = load { i1, i64, i1 }, { i1, i64, i1 }* %198, align 4 - %.fca.0.extract.i899.2 = extractvalue { i1, i64, i1 } %199, 0 - %.fca.1.extract.i900.2 = extractvalue { i1, i64, i1 } %199, 1 - br i1 %.fca.0.extract.i899.2, label %cond_300_case_1.i.2, label %cond_300_case_0.i.2 + %.fca.0.extract.i893.2 = extractvalue { i1, i64, i1 } %199, 0 + %.fca.1.extract.i894.2 = extractvalue { i1, i64, i1 } %199, 1 + br i1 %.fca.0.extract.i893.2, label %cond_300_case_1.i.2, label %cond_300_case_0.i.2 cond_300_case_0.i.2: ; preds = %__hugr__.array.__read_bool.3.271.exit.1 %.fca.2.extract.i.2 = extractvalue { i1, i64, i1 } %199, 2 br label %__hugr__.array.__read_bool.3.271.exit.2 cond_300_case_1.i.2: ; preds = %__hugr__.array.__read_bool.3.271.exit.1 - %read_bool.i.2 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.2) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.2) + %read_bool.i.2 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.2) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.2) br label %__hugr__.array.__read_bool.3.271.exit.2 __hugr__.array.__read_bool.3.271.exit.2: ; preds = %cond_300_case_1.i.2, %cond_300_case_0.i.2 @@ -588,17 +588,17 @@ __hugr__.array.__read_bool.3.271.exit.2: ; preds = %cond_300_case_1.i.2 %202 = getelementptr inbounds i8, i8* %84, i64 72 %203 = bitcast i8* %202 to { i1, i64, i1 }* %204 = load { i1, i64, i1 }, { i1, i64, i1 }* %203, align 4 - %.fca.0.extract.i899.3 = extractvalue { i1, i64, i1 } %204, 0 - %.fca.1.extract.i900.3 = extractvalue { i1, i64, i1 } %204, 1 - br i1 %.fca.0.extract.i899.3, label %cond_300_case_1.i.3, label %cond_300_case_0.i.3 + %.fca.0.extract.i893.3 = extractvalue { i1, i64, i1 } %204, 0 + %.fca.1.extract.i894.3 = extractvalue { i1, i64, i1 } %204, 1 + br i1 %.fca.0.extract.i893.3, label %cond_300_case_1.i.3, label %cond_300_case_0.i.3 cond_300_case_0.i.3: ; preds = %__hugr__.array.__read_bool.3.271.exit.2 %.fca.2.extract.i.3 = extractvalue { i1, i64, i1 } %204, 2 br label %__hugr__.array.__read_bool.3.271.exit.3 cond_300_case_1.i.3: ; preds = %__hugr__.array.__read_bool.3.271.exit.2 - %read_bool.i.3 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.3) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.3) + %read_bool.i.3 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.3) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.3) br label %__hugr__.array.__read_bool.3.271.exit.3 __hugr__.array.__read_bool.3.271.exit.3: ; preds = %cond_300_case_1.i.3, %cond_300_case_0.i.3 @@ -609,17 +609,17 @@ __hugr__.array.__read_bool.3.271.exit.3: ; preds = %cond_300_case_1.i.3 %207 = getelementptr inbounds i8, i8* %84, i64 96 %208 = bitcast i8* %207 to { i1, i64, i1 }* %209 = load { i1, i64, i1 }, { i1, i64, i1 }* %208, align 4 - %.fca.0.extract.i899.4 = extractvalue { i1, i64, i1 } %209, 0 - %.fca.1.extract.i900.4 = extractvalue { i1, i64, i1 } %209, 1 - br i1 %.fca.0.extract.i899.4, label %cond_300_case_1.i.4, label %cond_300_case_0.i.4 + %.fca.0.extract.i893.4 = extractvalue { i1, i64, i1 } %209, 0 + %.fca.1.extract.i894.4 = extractvalue { i1, i64, i1 } %209, 1 + br i1 %.fca.0.extract.i893.4, label %cond_300_case_1.i.4, label %cond_300_case_0.i.4 cond_300_case_0.i.4: ; preds = %__hugr__.array.__read_bool.3.271.exit.3 %.fca.2.extract.i.4 = extractvalue { i1, i64, i1 } %209, 2 br label %__hugr__.array.__read_bool.3.271.exit.4 cond_300_case_1.i.4: ; preds = %__hugr__.array.__read_bool.3.271.exit.3 - %read_bool.i.4 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.4) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.4) + %read_bool.i.4 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.4) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.4) br label %__hugr__.array.__read_bool.3.271.exit.4 __hugr__.array.__read_bool.3.271.exit.4: ; preds = %cond_300_case_1.i.4, %cond_300_case_0.i.4 @@ -630,17 +630,17 @@ __hugr__.array.__read_bool.3.271.exit.4: ; preds = %cond_300_case_1.i.4 %212 = getelementptr inbounds i8, i8* %84, i64 120 %213 = bitcast i8* %212 to { i1, i64, i1 }* %214 = load { i1, i64, i1 }, { i1, i64, i1 }* %213, align 4 - %.fca.0.extract.i899.5 = extractvalue { i1, i64, i1 } %214, 0 - %.fca.1.extract.i900.5 = extractvalue { i1, i64, i1 } %214, 1 - br i1 %.fca.0.extract.i899.5, label %cond_300_case_1.i.5, label %cond_300_case_0.i.5 + %.fca.0.extract.i893.5 = extractvalue { i1, i64, i1 } %214, 0 + %.fca.1.extract.i894.5 = extractvalue { i1, i64, i1 } %214, 1 + br i1 %.fca.0.extract.i893.5, label %cond_300_case_1.i.5, label %cond_300_case_0.i.5 cond_300_case_0.i.5: ; preds = %__hugr__.array.__read_bool.3.271.exit.4 %.fca.2.extract.i.5 = extractvalue { i1, i64, i1 } %214, 2 br label %__hugr__.array.__read_bool.3.271.exit.5 cond_300_case_1.i.5: ; preds = %__hugr__.array.__read_bool.3.271.exit.4 - %read_bool.i.5 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.5) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.5) + %read_bool.i.5 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.5) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.5) br label %__hugr__.array.__read_bool.3.271.exit.5 __hugr__.array.__read_bool.3.271.exit.5: ; preds = %cond_300_case_1.i.5, %cond_300_case_0.i.5 @@ -651,17 +651,17 @@ __hugr__.array.__read_bool.3.271.exit.5: ; preds = %cond_300_case_1.i.5 %217 = getelementptr inbounds i8, i8* %84, i64 144 %218 = bitcast i8* %217 to { i1, i64, i1 }* %219 = load { i1, i64, i1 }, { i1, i64, i1 }* %218, align 4 - %.fca.0.extract.i899.6 = extractvalue { i1, i64, i1 } %219, 0 - %.fca.1.extract.i900.6 = extractvalue { i1, i64, i1 } %219, 1 - br i1 %.fca.0.extract.i899.6, label %cond_300_case_1.i.6, label %cond_300_case_0.i.6 + %.fca.0.extract.i893.6 = extractvalue { i1, i64, i1 } %219, 0 + %.fca.1.extract.i894.6 = extractvalue { i1, i64, i1 } %219, 1 + br i1 %.fca.0.extract.i893.6, label %cond_300_case_1.i.6, label %cond_300_case_0.i.6 cond_300_case_0.i.6: ; preds = %__hugr__.array.__read_bool.3.271.exit.5 %.fca.2.extract.i.6 = extractvalue { i1, i64, i1 } %219, 2 br label %__hugr__.array.__read_bool.3.271.exit.6 cond_300_case_1.i.6: ; preds = %__hugr__.array.__read_bool.3.271.exit.5 - %read_bool.i.6 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.6) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.6) + %read_bool.i.6 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.6) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.6) br label %__hugr__.array.__read_bool.3.271.exit.6 __hugr__.array.__read_bool.3.271.exit.6: ; preds = %cond_300_case_1.i.6, %cond_300_case_0.i.6 @@ -672,17 +672,17 @@ __hugr__.array.__read_bool.3.271.exit.6: ; preds = %cond_300_case_1.i.6 %222 = getelementptr inbounds i8, i8* %84, i64 168 %223 = bitcast i8* %222 to { i1, i64, i1 }* %224 = load { i1, i64, i1 }, { i1, i64, i1 }* %223, align 4 - %.fca.0.extract.i899.7 = extractvalue { i1, i64, i1 } %224, 0 - %.fca.1.extract.i900.7 = extractvalue { i1, i64, i1 } %224, 1 - br i1 %.fca.0.extract.i899.7, label %cond_300_case_1.i.7, label %cond_300_case_0.i.7 + %.fca.0.extract.i893.7 = extractvalue { i1, i64, i1 } %224, 0 + %.fca.1.extract.i894.7 = extractvalue { i1, i64, i1 } %224, 1 + br i1 %.fca.0.extract.i893.7, label %cond_300_case_1.i.7, label %cond_300_case_0.i.7 cond_300_case_0.i.7: ; preds = %__hugr__.array.__read_bool.3.271.exit.6 %.fca.2.extract.i.7 = extractvalue { i1, i64, i1 } %224, 2 br label %__hugr__.array.__read_bool.3.271.exit.7 cond_300_case_1.i.7: ; preds = %__hugr__.array.__read_bool.3.271.exit.6 - %read_bool.i.7 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.7) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.7) + %read_bool.i.7 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.7) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.7) br label %__hugr__.array.__read_bool.3.271.exit.7 __hugr__.array.__read_bool.3.271.exit.7: ; preds = %cond_300_case_1.i.7, %cond_300_case_0.i.7 @@ -693,17 +693,17 @@ __hugr__.array.__read_bool.3.271.exit.7: ; preds = %cond_300_case_1.i.7 %227 = getelementptr inbounds i8, i8* %84, i64 192 %228 = bitcast i8* %227 to { i1, i64, i1 }* %229 = load { i1, i64, i1 }, { i1, i64, i1 }* %228, align 4 - %.fca.0.extract.i899.8 = extractvalue { i1, i64, i1 } %229, 0 - %.fca.1.extract.i900.8 = extractvalue { i1, i64, i1 } %229, 1 - br i1 %.fca.0.extract.i899.8, label %cond_300_case_1.i.8, label %cond_300_case_0.i.8 + %.fca.0.extract.i893.8 = extractvalue { i1, i64, i1 } %229, 0 + %.fca.1.extract.i894.8 = extractvalue { i1, i64, i1 } %229, 1 + br i1 %.fca.0.extract.i893.8, label %cond_300_case_1.i.8, label %cond_300_case_0.i.8 cond_300_case_0.i.8: ; preds = %__hugr__.array.__read_bool.3.271.exit.7 %.fca.2.extract.i.8 = extractvalue { i1, i64, i1 } %229, 2 br label %__hugr__.array.__read_bool.3.271.exit.8 cond_300_case_1.i.8: ; preds = %__hugr__.array.__read_bool.3.271.exit.7 - %read_bool.i.8 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.8) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.8) + %read_bool.i.8 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.8) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.8) br label %__hugr__.array.__read_bool.3.271.exit.8 __hugr__.array.__read_bool.3.271.exit.8: ; preds = %cond_300_case_1.i.8, %cond_300_case_0.i.8 @@ -714,17 +714,17 @@ __hugr__.array.__read_bool.3.271.exit.8: ; preds = %cond_300_case_1.i.8 %232 = getelementptr inbounds i8, i8* %84, i64 216 %233 = bitcast i8* %232 to { i1, i64, i1 }* %234 = load { i1, i64, i1 }, { i1, i64, i1 }* %233, align 4 - %.fca.0.extract.i899.9 = extractvalue { i1, i64, i1 } %234, 0 - %.fca.1.extract.i900.9 = extractvalue { i1, i64, i1 } %234, 1 - br i1 %.fca.0.extract.i899.9, label %cond_300_case_1.i.9, label %cond_300_case_0.i.9 + %.fca.0.extract.i893.9 = extractvalue { i1, i64, i1 } %234, 0 + %.fca.1.extract.i894.9 = extractvalue { i1, i64, i1 } %234, 1 + br i1 %.fca.0.extract.i893.9, label %cond_300_case_1.i.9, label %cond_300_case_0.i.9 cond_300_case_0.i.9: ; preds = %__hugr__.array.__read_bool.3.271.exit.8 %.fca.2.extract.i.9 = extractvalue { i1, i64, i1 } %234, 2 br label %__hugr__.array.__read_bool.3.271.exit.9 cond_300_case_1.i.9: ; preds = %__hugr__.array.__read_bool.3.271.exit.8 - %read_bool.i.9 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i900.9) - tail call void @___dec_future_refcount(i64 %.fca.1.extract.i900.9) + %read_bool.i.9 = tail call i1 @___read_future_bool(i64 %.fca.1.extract.i894.9) + tail call void @___dec_future_refcount(i64 %.fca.1.extract.i894.9) br label %__hugr__.array.__read_bool.3.271.exit.9 __hugr__.array.__read_bool.3.271.exit.9: ; preds = %cond_300_case_1.i.9, %cond_300_case_0.i.9 @@ -738,9 +738,9 @@ __hugr__.array.__read_bool.3.271.exit.9: ; preds = %cond_300_case_1.i.9 %238 = and i64 %237, 1023 store i64 %238, i64* %189, align 4 %239 = icmp eq i64 %238, 0 - br i1 %239, label %__barray_check_none_borrowed.exit905, label %mask_block_err.i904 + br i1 %239, label %__barray_check_none_borrowed.exit899, label %mask_block_err.i898 -__barray_check_none_borrowed.exit905: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 +__barray_check_none_borrowed.exit899: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 %out_arr_alloca = alloca <{ i32, i32, i1*, i1* }>, align 8 %x_ptr = getelementptr inbounds <{ i32, i32, i1*, i1* }>, <{ i32, i32, i1*, i1* }>* %out_arr_alloca, i64 0, i32 0 %y_ptr = getelementptr inbounds <{ i32, i32, i1*, i1* }>, <{ i32, i32, i1*, i1* }>* %out_arr_alloca, i64 0, i32 1 @@ -756,52 +756,52 @@ __barray_check_none_borrowed.exit905: ; preds = %__hugr__.array.__re store i8* %187, i8** %242, align 8 store i1* %.sub, i1** %mask_ptr, align 8 call void @print_bool_arr(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @res_cs.46C3C4B5.0, i64 0, i64 0), i64 15, <{ i32, i32, i1*, i1* }>* nonnull %out_arr_alloca) - br label %__barray_check_bounds.exit913 + br label %__barray_check_bounds.exit907 -mask_block_err.i904: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 +mask_block_err.i898: ; preds = %__hugr__.array.__read_bool.3.271.exit.9 tail call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit913: ; preds = %cond_exit_95.1, %__barray_check_none_borrowed.exit905 - %"90_0.sroa.0.0972" = phi i64 [ 0, %__barray_check_none_borrowed.exit905 ], [ %252, %cond_exit_95.1 ] - %243 = or i64 %"90_0.sroa.0.0972", 1 - %244 = lshr i64 %"90_0.sroa.0.0972", 6 +__barray_check_bounds.exit907: ; preds = %cond_exit_95.1, %__barray_check_none_borrowed.exit899 + %"90_0.sroa.0.0966" = phi i64 [ 0, %__barray_check_none_borrowed.exit899 ], [ %252, %cond_exit_95.1 ] + %243 = or i64 %"90_0.sroa.0.0966", 1 + %244 = lshr i64 %"90_0.sroa.0.0966", 6 %245 = getelementptr inbounds i64, i64* %7, i64 %244 %246 = load i64, i64* %245, align 4 - %247 = and i64 %"90_0.sroa.0.0972", 62 + %247 = and i64 %"90_0.sroa.0.0966", 62 %248 = shl nuw i64 1, %247 %249 = and i64 %246, %248 - %.not.i914 = icmp eq i64 %249, 0 - br i1 %.not.i914, label %panic.i915, label %cond_exit_95 + %.not.i908 = icmp eq i64 %249, 0 + br i1 %.not.i908, label %panic.i909, label %cond_exit_95 -panic.i915: ; preds = %cond_exit_95, %__barray_check_bounds.exit913 +panic.i909: ; preds = %cond_exit_95, %__barray_check_bounds.exit907 call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -cond_exit_95: ; preds = %__barray_check_bounds.exit913 +cond_exit_95: ; preds = %__barray_check_bounds.exit907 %250 = xor i64 %246, %248 store i64 %250, i64* %245, align 4 - %251 = getelementptr inbounds i64, i64* %5, i64 %"90_0.sroa.0.0972" - store i64 %"90_0.sroa.0.0972", i64* %251, align 4 - %252 = add nuw nsw i64 %"90_0.sroa.0.0972", 2 - %253 = lshr i64 %"90_0.sroa.0.0972", 6 + %251 = getelementptr inbounds i64, i64* %5, i64 %"90_0.sroa.0.0966" + store i64 %"90_0.sroa.0.0966", i64* %251, align 4 + %252 = add nuw nsw i64 %"90_0.sroa.0.0966", 2 + %253 = lshr i64 %"90_0.sroa.0.0966", 6 %254 = getelementptr inbounds i64, i64* %7, i64 %253 %255 = load i64, i64* %254, align 4 %256 = and i64 %243, 63 %257 = shl nuw i64 1, %256 %258 = and i64 %255, %257 - %.not.i914.1 = icmp eq i64 %258, 0 - br i1 %.not.i914.1, label %panic.i915, label %cond_exit_95.1 + %.not.i908.1 = icmp eq i64 %258, 0 + br i1 %.not.i908.1, label %panic.i909, label %cond_exit_95.1 cond_exit_95.1: ; preds = %cond_exit_95 %259 = xor i64 %255, %257 store i64 %259, i64* %254, align 4 %260 = getelementptr inbounds i64, i64* %5, i64 %243 store i64 %243, i64* %260, align 4 - %exitcond983.not.1 = icmp eq i64 %252, 100 - br i1 %exitcond983.not.1, label %loop_out212, label %__barray_check_bounds.exit913 + %exitcond977.not.1 = icmp eq i64 %252, 100 + br i1 %exitcond977.not.1, label %loop_out208, label %__barray_check_bounds.exit907 -loop_out212: ; preds = %cond_exit_95.1 +loop_out208: ; preds = %cond_exit_95.1 %261 = getelementptr inbounds i8, i8* %6, i64 8 %262 = bitcast i8* %261 to i64* %263 = load i64, i64* %262, align 4 @@ -811,9 +811,9 @@ loop_out212: ; preds = %cond_exit_95.1 %266 = icmp eq i64 %265, 0 %267 = icmp eq i64 %264, 0 %or.cond = select i1 %266, i1 %267, i1 false - br i1 %or.cond, label %__barray_check_none_borrowed.exit921, label %mask_block_err.i920 + br i1 %or.cond, label %__barray_check_none_borrowed.exit915, label %mask_block_err.i914 -__barray_check_none_borrowed.exit921: ; preds = %loop_out212 +__barray_check_none_borrowed.exit915: ; preds = %loop_out208 %268 = call i8* @heap_alloc(i64 800) %269 = bitcast i8* %268 to i64* %270 = call i8* @heap_alloc(i64 16) @@ -827,62 +827,62 @@ __barray_check_none_borrowed.exit921: ; preds = %loop_out212 %274 = load i64, i64* %7, align 4 %275 = icmp eq i64 %274, 0 %276 = icmp eq i64 %273, 0 - %or.cond986 = select i1 %275, i1 %276, i1 false - br i1 %or.cond986, label %__barray_check_none_borrowed.exit926, label %mask_block_err.i925 + %or.cond980 = select i1 %275, i1 %276, i1 false + br i1 %or.cond980, label %__barray_check_none_borrowed.exit920, label %mask_block_err.i919 -mask_block_err.i920: ; preds = %loop_out212 +mask_block_err.i914: ; preds = %loop_out208 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_none_borrowed.exit926: ; preds = %__barray_check_none_borrowed.exit921 - %out_arr_alloca287 = alloca <{ i32, i32, i64*, i1* }>, align 8 - %x_ptr288 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 0 - %y_ptr289 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 1 - %arr_ptr290 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 2 - %mask_ptr291 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca287, i64 0, i32 3 +__barray_check_none_borrowed.exit920: ; preds = %__barray_check_none_borrowed.exit915 + %out_arr_alloca282 = alloca <{ i32, i32, i64*, i1* }>, align 8 + %x_ptr283 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 0 + %y_ptr284 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 1 + %arr_ptr285 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 2 + %mask_ptr286 = getelementptr inbounds <{ i32, i32, i64*, i1* }>, <{ i32, i32, i64*, i1* }>* %out_arr_alloca282, i64 0, i32 3 %277 = alloca [100 x i1], align 1 - %.sub635 = getelementptr inbounds [100 x i1], [100 x i1]* %277, i64 0, i64 0 + %.sub629 = getelementptr inbounds [100 x i1], [100 x i1]* %277, i64 0, i64 0 %278 = bitcast [100 x i1]* %277 to i8* call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(100) %278, i8 0, i64 100, i1 false) - store i32 100, i32* %x_ptr288, align 8 - store i32 1, i32* %y_ptr289, align 4 - %279 = bitcast i64** %arr_ptr290 to i8** + store i32 100, i32* %x_ptr283, align 8 + store i32 1, i32* %y_ptr284, align 4 + %279 = bitcast i64** %arr_ptr285 to i8** store i8* %4, i8** %279, align 8 - store i1* %.sub635, i1** %mask_ptr291, align 8 - call void @print_int_arr(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @res_is.F21393DB.0, i64 0, i64 0), i64 14, <{ i32, i32, i64*, i1* }>* nonnull %out_arr_alloca287) - br label %__barray_check_bounds.exit934 + store i1* %.sub629, i1** %mask_ptr286, align 8 + call void @print_int_arr(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @res_is.F21393DB.0, i64 0, i64 0), i64 14, <{ i32, i32, i64*, i1* }>* nonnull %out_arr_alloca282) + br label %__barray_check_bounds.exit928 -mask_block_err.i925: ; preds = %__barray_check_none_borrowed.exit921 +mask_block_err.i919: ; preds = %__barray_check_none_borrowed.exit915 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_bounds.exit934: ; preds = %cond_exit_130, %__barray_check_none_borrowed.exit926 - %"125_0.sroa.0.0974" = phi i64 [ 0, %__barray_check_none_borrowed.exit926 ], [ %280, %cond_exit_130 ] - %280 = add nuw nsw i64 %"125_0.sroa.0.0974", 1 - %281 = lshr i64 %"125_0.sroa.0.0974", 6 +__barray_check_bounds.exit928: ; preds = %cond_exit_130, %__barray_check_none_borrowed.exit920 + %"125_0.sroa.0.0968" = phi i64 [ 0, %__barray_check_none_borrowed.exit920 ], [ %280, %cond_exit_130 ] + %280 = add nuw nsw i64 %"125_0.sroa.0.0968", 1 + %281 = lshr i64 %"125_0.sroa.0.0968", 6 %282 = getelementptr inbounds i64, i64* %3, i64 %281 %283 = load i64, i64* %282, align 4 - %284 = and i64 %"125_0.sroa.0.0974", 63 + %284 = and i64 %"125_0.sroa.0.0968", 63 %285 = shl nuw i64 1, %284 %286 = and i64 %283, %285 - %.not.i935 = icmp eq i64 %286, 0 - br i1 %.not.i935, label %panic.i936, label %cond_exit_130 + %.not.i929 = icmp eq i64 %286, 0 + br i1 %.not.i929, label %panic.i930, label %cond_exit_130 -panic.i936: ; preds = %__barray_check_bounds.exit934 +panic.i930: ; preds = %__barray_check_bounds.exit928 call void @panic(i32 1002, i8* getelementptr inbounds ([57 x i8], [57 x i8]* @"e_Array alre.5A300C2A.0", i64 0, i64 0)) unreachable -cond_exit_130: ; preds = %__barray_check_bounds.exit934 - %287 = sitofp i64 %"125_0.sroa.0.0974" to double +cond_exit_130: ; preds = %__barray_check_bounds.exit928 + %287 = sitofp i64 %"125_0.sroa.0.0968" to double %288 = fmul double %287, 6.250000e-02 %289 = xor i64 %283, %285 store i64 %289, i64* %282, align 4 - %290 = getelementptr inbounds double, double* %1, i64 %"125_0.sroa.0.0974" + %290 = getelementptr inbounds double, double* %1, i64 %"125_0.sroa.0.0968" store double %288, double* %290, align 8 - %exitcond984.not = icmp eq i64 %280, 100 - br i1 %exitcond984.not, label %loop_out299, label %__barray_check_bounds.exit934 + %exitcond978.not = icmp eq i64 %280, 100 + br i1 %exitcond978.not, label %loop_out294, label %__barray_check_bounds.exit928 -loop_out299: ; preds = %cond_exit_130 +loop_out294: ; preds = %cond_exit_130 %291 = getelementptr inbounds i8, i8* %2, i64 8 %292 = bitcast i8* %291 to i64* %293 = load i64, i64* %292, align 4 @@ -891,10 +891,10 @@ loop_out299: ; preds = %cond_exit_130 %295 = load i64, i64* %3, align 4 %296 = icmp eq i64 %295, 0 %297 = icmp eq i64 %294, 0 - %or.cond987 = select i1 %296, i1 %297, i1 false - br i1 %or.cond987, label %__barray_check_none_borrowed.exit942, label %mask_block_err.i941 + %or.cond981 = select i1 %296, i1 %297, i1 false + br i1 %or.cond981, label %__barray_check_none_borrowed.exit936, label %mask_block_err.i935 -__barray_check_none_borrowed.exit942: ; preds = %loop_out299 +__barray_check_none_borrowed.exit936: ; preds = %loop_out294 %298 = call i8* @heap_alloc(i64 800) %299 = bitcast i8* %298 to double* %300 = call i8* @heap_alloc(i64 16) @@ -908,32 +908,32 @@ __barray_check_none_borrowed.exit942: ; preds = %loop_out299 %304 = load i64, i64* %3, align 4 %305 = icmp eq i64 %304, 0 %306 = icmp eq i64 %303, 0 - %or.cond988 = select i1 %305, i1 %306, i1 false - br i1 %or.cond988, label %__barray_check_none_borrowed.exit947, label %mask_block_err.i946 + %or.cond982 = select i1 %305, i1 %306, i1 false + br i1 %or.cond982, label %__barray_check_none_borrowed.exit941, label %mask_block_err.i940 -mask_block_err.i941: ; preds = %loop_out299 +mask_block_err.i935: ; preds = %loop_out294 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable -__barray_check_none_borrowed.exit947: ; preds = %__barray_check_none_borrowed.exit942 - %out_arr_alloca377 = alloca <{ i32, i32, double*, i1* }>, align 8 - %x_ptr378 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 0 - %y_ptr379 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 1 - %arr_ptr380 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 2 - %mask_ptr381 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca377, i64 0, i32 3 +__barray_check_none_borrowed.exit941: ; preds = %__barray_check_none_borrowed.exit936 + %out_arr_alloca371 = alloca <{ i32, i32, double*, i1* }>, align 8 + %x_ptr372 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 0 + %y_ptr373 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 1 + %arr_ptr374 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 2 + %mask_ptr375 = getelementptr inbounds <{ i32, i32, double*, i1* }>, <{ i32, i32, double*, i1* }>* %out_arr_alloca371, i64 0, i32 3 %307 = alloca [100 x i1], align 1 - %.sub736 = getelementptr inbounds [100 x i1], [100 x i1]* %307, i64 0, i64 0 + %.sub730 = getelementptr inbounds [100 x i1], [100 x i1]* %307, i64 0, i64 0 %308 = bitcast [100 x i1]* %307 to i8* call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(100) %308, i8 0, i64 100, i1 false) - store i32 100, i32* %x_ptr378, align 8 - store i32 1, i32* %y_ptr379, align 4 - %309 = bitcast double** %arr_ptr380 to i8** + store i32 100, i32* %x_ptr372, align 8 + store i32 1, i32* %y_ptr373, align 4 + %309 = bitcast double** %arr_ptr374 to i8** store i8* %0, i8** %309, align 8 - store i1* %.sub736, i1** %mask_ptr381, align 8 - call void @print_float_arr(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @res_fs.CBD4AF54.0, i64 0, i64 0), i64 16, <{ i32, i32, double*, i1* }>* nonnull %out_arr_alloca377) + store i1* %.sub730, i1** %mask_ptr375, align 8 + call void @print_float_arr(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @res_fs.CBD4AF54.0, i64 0, i64 0), i64 16, <{ i32, i32, double*, i1* }>* nonnull %out_arr_alloca371) ret void -mask_block_err.i946: ; preds = %__barray_check_none_borrowed.exit942 +mask_block_err.i940: ; preds = %__barray_check_none_borrowed.exit936 call void @panic(i32 1002, i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"e_Some array.A77EF32E.0", i64 0, i64 0)) unreachable } From c3a04a611fa784846fab368a135e159c27c406a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= Date: Wed, 17 Dec 2025 12:44:39 +0000 Subject: [PATCH 36/48] feat: Remove order edges in NormalizeGuppy pass --- tket-py/src/passes.rs | 7 +++++-- tket-py/tket/_tket/passes.pyi | 2 ++ tket-py/tket/passes.py | 2 ++ tket-qsystem/tests/guppy_opt.rs | 4 ++-- tket/src/passes/guppy.rs | 21 +++++++++++++++++++++ 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/tket-py/src/passes.rs b/tket-py/src/passes.rs index 8e254209b..129b86256 100644 --- a/tket-py/src/passes.rs +++ b/tket-py/src/passes.rs @@ -63,8 +63,9 @@ create_py_exception!( /// - constant_folding: Whether to constant fold the program. /// - remove_dead_funcs: Whether to remove dead functions. /// - inline_dfgs: Whether to inline DFG operations. +/// - remove_redundant_order_edges: Whether to remove redundant order edges. #[pyfunction] -#[pyo3(signature = (circ, *, simplify_cfgs = true, remove_tuple_untuple = true, constant_folding = false, remove_dead_funcs = true, inline_dfgs = true))] +#[pyo3(signature = (circ, *, simplify_cfgs = true, remove_tuple_untuple = true, constant_folding = false, remove_dead_funcs = true, inline_dfgs = true, remove_redundant_order_edges = true))] fn normalize_guppy<'py>( circ: &Bound<'py, PyAny>, simplify_cfgs: bool, @@ -72,6 +73,7 @@ fn normalize_guppy<'py>( constant_folding: bool, remove_dead_funcs: bool, inline_dfgs: bool, + remove_redundant_order_edges: bool, ) -> PyResult> { let py = circ.py(); try_with_circ(circ, |mut circ, typ| { @@ -81,7 +83,8 @@ fn normalize_guppy<'py>( .remove_tuple_untuple(remove_tuple_untuple) .constant_folding(constant_folding) .remove_dead_funcs(remove_dead_funcs) - .inline_dfgs(inline_dfgs); + .inline_dfgs(inline_dfgs) + .remove_redundant_order_edges(remove_redundant_order_edges); pass.run(circ.hugr_mut()).convert_pyerrs()?; diff --git a/tket-py/tket/_tket/passes.pyi b/tket-py/tket/_tket/passes.pyi index 84a0521b7..0b009de05 100644 --- a/tket-py/tket/_tket/passes.pyi +++ b/tket-py/tket/_tket/passes.pyi @@ -28,6 +28,7 @@ def normalize_guppy( constant_folding: bool = False, remove_dead_funcs: bool = True, inline_dfgs: bool = True, + remove_redundant_order_edges: bool = True, ) -> CircuitClass: """Flatten the structure of a Guppy-generated program to enable additional optimisations. @@ -39,6 +40,7 @@ def normalize_guppy( - constant_folding: Whether to constant fold the program. - remove_dead_funcs: Whether to remove dead functions. - inline_dfgs: Whether to inline DFG operations. + - remove_redundant_order_edges: Whether to remove redundant order edges. """ def greedy_depth_reduce(circ: CircuitClass) -> tuple[CircuitClass, int]: diff --git a/tket-py/tket/passes.py b/tket-py/tket/passes.py index 42ee53022..73b1beca9 100644 --- a/tket-py/tket/passes.py +++ b/tket-py/tket/passes.py @@ -141,6 +141,7 @@ class NormalizeGuppy(ComposablePass): constant_folding: bool = True remove_dead_funcs: bool = True inline_dfgs: bool = True + remove_redundant_order_edges: bool = True """Flatten the structure of a Guppy-generated program to enable additional optimisations. @@ -171,6 +172,7 @@ def _normalize(self, hugr: Hugr, inplace: bool) -> PassResult: constant_folding=self.constant_folding, remove_dead_funcs=self.remove_dead_funcs, inline_dfgs=self.inline_dfgs, + remove_redundant_order_edges=self.remove_redundant_order_edges, ) new_hugr = Hugr.from_str(opt_program.to_str()) return PassResult.for_pass(self, hugr=new_hugr, inplace=inplace, result=None) diff --git a/tket-qsystem/tests/guppy_opt.rs b/tket-qsystem/tests/guppy_opt.rs index 50ea76209..8784bddba 100644 --- a/tket-qsystem/tests/guppy_opt.rs +++ b/tket-qsystem/tests/guppy_opt.rs @@ -82,7 +82,7 @@ fn count_gates(h: &impl HugrView) -> HashMap { #[case::nested_array("nested_array", None)] #[should_panic = "xfail"] #[case::angles("angles", Some(vec![ - ("tket.quantum.Rz", 2), ("tket.quantum.MeasureFree", 1), ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 1) + ("tket.quantum.Rz", 2), ("tket.quantum.QFree", 1), ("tket.quantum.Measure", 1), ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 1) ]))] #[should_panic = "xfail"] #[case::simple_cx("simple_cx", Some(vec![ @@ -98,7 +98,7 @@ fn count_gates(h: &impl HugrView) -> HashMap { ]))] #[should_panic = "xfail"] #[case::false_branch("false_branch", Some(vec![ - ("TKET1.tk1op", 1), ("tket.quantum.H", 1), ("tket.quantum.QAlloc", 1), ("tket.quantum.MeasureFree", 1) + ("tket.quantum.Measure", 1), ("tket.quantum.QFree", 1), ("tket.quantum.QAlloc", 1) ]))] #[should_panic = "xfail"] #[case::func_decls("func_decls", Some(vec![ diff --git a/tket/src/passes/guppy.rs b/tket/src/passes/guppy.rs index a1f407fa6..c2ce45a20 100644 --- a/tket/src/passes/guppy.rs +++ b/tket/src/passes/guppy.rs @@ -4,8 +4,10 @@ use hugr::Node; use hugr::algorithms::const_fold::{ConstFoldError, ConstantFoldPass}; use hugr::algorithms::inline_dfgs::InlineDFGsPass; use hugr::algorithms::normalize_cfgs::{NormalizeCFGError, NormalizeCFGPass}; +use hugr::algorithms::redundant_order_edges::RedundantOrderEdgesPass; use hugr::algorithms::untuple::{UntupleError, UntupleRecursive}; use hugr::algorithms::{ComposablePass, RemoveDeadFuncsError, RemoveDeadFuncsPass, UntuplePass}; +use hugr::hugr::HugrError; use hugr::hugr::hugrmut::HugrMut; use hugr::hugr::patch::inline_dfg::InlineDFGError; @@ -28,6 +30,8 @@ pub struct NormalizeGuppy { inline_dfgs: bool, /// Whether to squash BorrowArray borrow/return ops squash_borrows: bool, + /// Whether to remove redundant order edges. + remove_redundant_order_edges: bool, } impl NormalizeGuppy { @@ -61,6 +65,11 @@ impl NormalizeGuppy { self.squash_borrows = squash; self } + /// Set whether to remove redundant order edges. + pub fn remove_redundant_order_edges(&mut self, remove: bool) -> &mut Self { + self.remove_redundant_order_edges = remove; + self + } } impl Default for NormalizeGuppy { @@ -72,6 +81,7 @@ impl Default for NormalizeGuppy { dead_funcs: true, inline_dfgs: true, squash_borrows: true, + remove_redundant_order_edges: true, } } } @@ -107,6 +117,13 @@ impl + 'static> ComposablePass for NormalizeGuppy { .run(hugr) .unwrap_or_else(|e| match e {}); } + // Remove redundant order edges once all other structural rewrites have been applied. + if self.remove_redundant_order_edges { + RedundantOrderEdgesPass::default() + .recursive(true) + .run(hugr) + .map_err(NormalizeGuppyErrors::RedundantOrderEdges)?; + } Ok(()) } @@ -125,6 +142,9 @@ pub enum NormalizeGuppyErrors { DeadFuncs(RemoveDeadFuncsError), /// Error while inlining DFG operations. Inline(InlineDFGError), + /// Error while removing redundant order edges. + #[from(ignore)] + RedundantOrderEdges(HugrError), } #[cfg(test)] @@ -152,6 +172,7 @@ mod test { .constant_folding(false) .remove_dead_funcs(false) .inline_dfgs(false) + .remove_redundant_order_edges(false) .run(&mut hugr2) .unwrap(); From 59546a9ea0079ddf530e336cf2e5e397b41c614d Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Wed, 17 Dec 2025 17:31:37 +0000 Subject: [PATCH 37/48] New tests added but one of them failing --- tket/src/passes/gridsynth.rs | 162 ++++++++++++++++++++++++++++++++--- 1 file changed, 151 insertions(+), 11 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 820eacf8b..023a78c20 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -52,7 +52,7 @@ fn find_single_linked_output_by_index( let collected_ports: Vec<_> = ports.collect(); hugr.single_linked_output(node, collected_ports[port_idx]) - .unwrap() + .expect("Not yet set-up to handle cases where there are no previous nodes") } /// Find the constant node containing the angle to be inputted to the Rz gate. @@ -136,15 +136,22 @@ fn find_qubit_source(hugr: &mut Hugr, rz_node: Node) -> Node { /// Add a gridsynth gate to some previous node, which may or may not be a gridsynth gate, /// and connect fn add_gate_and_connect( - hugr: &mut Hugr, + hugr: &mut Hugr, prev_node: Node, op: hugr::ops::OpType, output_node: Node, + qubit_providing_node: Node, // the node providing qubit to Rz gate + qubit_providing_port: OutgoingPort // the output port providing qubit to Rz gate ) -> Node { let current_node = hugr.add_node_after(output_node, op); let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); - // Assuming there were no outgoing ports to begin with when deciding port offset - let src_port = ports[0]; + let src_port = if prev_node.index() == qubit_providing_node.index() { + qubit_providing_port + } + else { + ports[0] + } + // let src_port = ports[0]; let ports: Vec<_> = hugr.node_inputs(current_node).collect(); let dst_port = ports[0]; hugr.connect(prev_node, src_port, current_node, dst_port); @@ -154,12 +161,22 @@ fn add_gate_and_connect( fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) { // getting node that gave qubit to Rz gate - let mut prev_node = find_qubit_source(hugr, rz_node); + // let mut prev_node = find_qubit_source(hugr, rz_node); + // getting node and output port that gave qubit to Rz gate + let inputs: Vec<_> = hugr.node_inputs(rz_node).collect(); + let input_port = inputs[0]; + let (qubit_providing_node, qubit_providing_port) = hugr.single_linked_output(rz_node, input_port).unwrap(); + let mut prev_node = qubit_providing_node.clone(); + + // I need the outgoing port of this node that connects to the rz_node + // BUG! This won't necessarily be the 0th port, eg, if of a two qubit gate + // Replace with the outgoing port of the original prev_node. + // This needs to go into the first gridsynth gate // find output port let outputs: Vec<_> = hugr.node_outputs(rz_node).collect(); let output_port = outputs[0]; - let (next_node, _) = hugr.single_linked_input(rz_node, output_port).unwrap(); + let (next_node, dst_port) = hugr.single_linked_input(rz_node, output_port).unwrap(); // we have now inferred what we need to know from the Rz node we are replacing and can remove it hugr.remove_node(rz_node); @@ -180,11 +197,9 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) } let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); // Assuming there were no outgoing ports to begin with when deciding port offset - let src_port = ports[0]; - let ports: Vec<_> = hugr.node_inputs(next_node).collect(); - let dst_port = ports[0]; + let src_port = ports[0]; hugr.connect(prev_node, src_port, next_node, dst_port); - // println!("Inside panicking function: {}", hugr.mermaid_string()); + println!("Inside panicking function: {}", hugr.mermaid_string()); hugr.validate().unwrap_or_else(|e| panic!("{e}")); } @@ -225,10 +240,12 @@ mod tests { use crate::extension::rotation::ConstRotation; use crate::hugr::builder::{Container, DFGBuilder, Dataflow, HugrBuilder}; use crate::hugr::envelope::read_described_envelope; - use crate::hugr::extension::prelude::qb_t; + use crate::extension::bool::bool_type; + use crate::hugr::extension::prelude::{qb_t}; use crate::hugr::ops::Value; use crate::hugr::types::Signature; use hugr::NodeIndex; + use hugr::builder::DataflowHugr; use hugr_core::std_extensions::std_reg; fn build_rz_only_circ() -> (Hugr, Node) { @@ -250,6 +267,111 @@ mod tests { let rz_node = rz_nodes[0]; (circ, rz_node) } + + fn build_non_trivial_circ() -> Hugr { + // defining some angles for Rz gates in radians + let alpha = 0.23; + let beta = 1.78; + let inverse_angle = - alpha - beta; + + // defining builder for circuit + let qb_row= vec![qb_t(); 1]; + let meas_row = vec![bool_type(); 1]; + let mut builder = DFGBuilder::new(Signature::new(qb_row.clone(), meas_row.clone())).unwrap(); + let [q1] = builder.input_wires_arr(); + + // adding constant wires and nodes + let alpha_const = builder.add_constant(Value::extension( + ConstRotation::from_radians(alpha).unwrap(), + )); + let loaded_alpha = builder.load_const(&alpha_const); + let beta_const = builder.add_constant(Value::extension( + ConstRotation::from_radians(beta).unwrap(), + )); + let loaded_beta = builder.load_const(&beta_const); + let inverse_const = builder.add_constant(Value::extension( + ConstRotation::from_radians(inverse_angle).unwrap(), + )); + let loaded_inverse = builder.load_const(&inverse_const); + + // adding gates and measurements + let had1 = builder.add_dataflow_op(TketOp::H, [q1]).unwrap(); + let [q1] = had1.outputs_arr(); + let rz_alpha = builder.add_dataflow_op(TketOp::Rz, [q1, loaded_alpha]).unwrap(); + let [q1] = rz_alpha.outputs_arr(); + let rz_beta = builder.add_dataflow_op(TketOp::Rz, [q1, loaded_beta]).unwrap(); + let [q1] = rz_beta.outputs_arr(); + let rz_inverse = builder.add_dataflow_op(TketOp::Rz, [q1, loaded_inverse]).unwrap(); + let [q1] = rz_inverse.outputs_arr(); + let had2 = builder.add_dataflow_op(TketOp::H, [q1]).unwrap(); + let [q1] = had2.outputs_arr(); + let meas_res = builder.add_dataflow_op(TketOp::MeasureFree, [q1]) + .unwrap() + .out_wire(0); + + //println!("{}", builder.hugr().mermaid_string()); + + let mut circ = builder.finish_hugr_with_outputs([meas_res]).unwrap_or_else(|e| panic!("{e}")); + // let mut circ = builder.finish_hugr_with_outputs([q1, q2]).unwrap(); + circ + } + + fn build_non_trivial_circ_2qubits() -> Hugr { + // defining some angles for Rz gates in radians + let alpha = 0.23; + let beta = 1.78; + let inverse_angle = - alpha - beta; + + // defining builder for circuit + let qb_row= vec![qb_t(); 2]; + let meas_row = vec![bool_type(); 2]; + let mut builder = DFGBuilder::new(Signature::new(qb_row.clone(), meas_row.clone())).unwrap(); + let [q1, q2] = builder.input_wires_arr(); + + // adding constant wires and nodes + let alpha_const = builder.add_constant(Value::extension( + ConstRotation::from_radians(alpha).unwrap(), + )); + let loaded_alpha = builder.load_const(&alpha_const); + let beta_const = builder.add_constant(Value::extension( + ConstRotation::from_radians(beta).unwrap(), + )); + let loaded_beta = builder.load_const(&beta_const); + let inverse_const = builder.add_constant(Value::extension( + ConstRotation::from_radians(inverse_angle).unwrap(), + )); + let loaded_inverse = builder.load_const(&inverse_const); + + // adding gates and measurements + let had1 = builder.add_dataflow_op(TketOp::H, [q1]).unwrap(); + let [q1] = had1.outputs_arr(); + let rz_alpha = builder.add_dataflow_op(TketOp::Rz, [q1, loaded_alpha]).unwrap(); + let [q1] = rz_alpha.outputs_arr(); + let rz_beta = builder.add_dataflow_op(TketOp::Rz, [q1, loaded_beta]).unwrap(); + let [q1] = rz_beta.outputs_arr(); + let x = builder.add_dataflow_op(TketOp::X, [q2]).unwrap(); + let [q2] = x.outputs_arr(); + let cx1 = builder.add_dataflow_op(TketOp::CX, [q2, q1]).unwrap(); + let [q2, q1] = cx1.outputs_arr(); + let rz_inverse = builder.add_dataflow_op(TketOp::Rz, [q1, loaded_inverse]).unwrap(); + let [q1] = rz_inverse.outputs_arr(); + let cx2 = builder.add_dataflow_op(TketOp::CX, [q2, q1]).unwrap(); + let [q2, q1] = cx2.outputs_arr(); + let had2 = builder.add_dataflow_op(TketOp::H, [q1]).unwrap(); + let [q1] = had2.outputs_arr(); + let meas_res1 = builder.add_dataflow_op(TketOp::MeasureFree, [q1]) + .unwrap() + .out_wire(0); + let meas_res2 = builder.add_dataflow_op(TketOp::MeasureFree, [q2]) + .unwrap() + .out_wire(0); + + //println!("{}", builder.hugr().mermaid_string()); + + let mut circ = builder.finish_hugr_with_outputs([meas_res1, meas_res2]).unwrap_or_else(|e| panic!("{e}")); + // let mut circ = builder.finish_hugr_with_outputs([q1, q2]).unwrap(); + circ + } fn import_guppy(path: &'static str) -> Hugr { let f = File::open(path).unwrap(); @@ -367,4 +489,22 @@ mod tests { apply_gridsynth_pass(imported_hugr, epsilon); println!("after: {}", imported_hugr.mermaid_string()); } + + #[test] + fn test_non_trivial_circ_1qubit() { + let epsilon = 1e-2; + let mut hugr = build_non_trivial_circ(); + + apply_gridsynth_pass(&mut hugr, epsilon); + } + + #[test] + fn test_non_trivial_circ_2qubits() { + let epsilon = 1e-2; + let mut hugr = build_non_trivial_circ_2qubits(); + println!("before gridsynth: {}", hugr.mermaid_string()); + + apply_gridsynth_pass(&mut hugr, epsilon); + + } } From 493f1d15388205ecdcc898d2ee8bcd21c12d097e Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Wed, 17 Dec 2025 17:36:44 +0000 Subject: [PATCH 38/48] Fixed bug: unable to handle 2 qubit gates --- tket/src/passes/gridsynth.rs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 023a78c20..4fc7aa09d 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -4,6 +4,7 @@ use crate::extension::rotation::ConstRotation; use crate::hugr::hugr::hugrmut::HugrMut; use crate::hugr::HugrView; use crate::hugr::{Node, Port}; +use crate::hugr::NodeIndex; use crate::passes::guppy::NormalizeGuppy; use crate::TketOp; use crate::{hugr, op_matches, Hugr}; @@ -150,8 +151,7 @@ fn add_gate_and_connect( } else { ports[0] - } - // let src_port = ports[0]; + }; let ports: Vec<_> = hugr.node_inputs(current_node).collect(); let dst_port = ports[0]; hugr.connect(prev_node, src_port, current_node, dst_port); @@ -160,19 +160,12 @@ fn add_gate_and_connect( } fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) { - // getting node that gave qubit to Rz gate - // let mut prev_node = find_qubit_source(hugr, rz_node); // getting node and output port that gave qubit to Rz gate let inputs: Vec<_> = hugr.node_inputs(rz_node).collect(); let input_port = inputs[0]; let (qubit_providing_node, qubit_providing_port) = hugr.single_linked_output(rz_node, input_port).unwrap(); let mut prev_node = qubit_providing_node.clone(); - // I need the outgoing port of this node that connects to the rz_node - // BUG! This won't necessarily be the 0th port, eg, if of a two qubit gate - // Replace with the outgoing port of the original prev_node. - // This needs to go into the first gridsynth gate - // find output port let outputs: Vec<_> = hugr.node_outputs(rz_node).collect(); let output_port = outputs[0]; @@ -186,11 +179,14 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) // recursively adding next gate in gates to prev_node for gate in gates.chars() { if gate == 'H' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::H.into(), next_node); + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::H.into(), next_node, + qubit_providing_node, qubit_providing_port); } else if gate == 'S' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::S.into(), next_node); + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::S.into(), next_node, + qubit_providing_node, qubit_providing_port); } else if gate == 'T' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::T.into(), next_node); + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::T.into(), next_node, + qubit_providing_node, qubit_providing_port); } else if gate == 'W' { break; // Ignoring global phases for now. } From c78ad27ab8c38988b636f3b6bbea1949ebe8e073 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Thu, 18 Dec 2025 16:02:03 +0000 Subject: [PATCH 39/48] Added interpreting of x gates --- tket/src/passes/gridsynth.rs | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 4fc7aa09d..3cd878d89 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -123,7 +123,7 @@ fn apply_gridsynth(hugr: &mut Hugr, epsilon: f64, rz_node: Node) -> String { let mut gridsynth_config = config_from_theta_epsilon(theta, epsilon, seed, verbose, up_to_phase); let gates = gridsynth_gates(&mut gridsynth_config); - + println!("{}", gates.gates); gates.gates } @@ -146,10 +146,15 @@ fn add_gate_and_connect( ) -> Node { let current_node = hugr.add_node_after(output_node, op); let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); + + // if the previous node was the qubit_providing_node then it could have multiple + // outputs (eg, if multi-qubit gate and so need to be explicit about port) let src_port = if prev_node.index() == qubit_providing_node.index() { qubit_providing_port } else { + // the ops generated by gridsynth are all single input single output gates, so + // it is safe to assume that there is only one output port ports[0] }; let ports: Vec<_> = hugr.node_inputs(current_node).collect(); @@ -157,7 +162,8 @@ fn add_gate_and_connect( hugr.connect(prev_node, src_port, current_node, dst_port); current_node -} +} // TO DO: reduce number of arguments to this function. Six is too many. + // I think that there must be a better way of doing this. fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) { // getting node and output port that gave qubit to Rz gate @@ -187,15 +193,20 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) } else if gate == 'T' { prev_node = add_gate_and_connect(hugr, prev_node, TketOp::T.into(), next_node, qubit_providing_node, qubit_providing_port); + } else if gate == 'X' { + prev_node = add_gate_and_connect(hugr, prev_node, TketOp::X.into(), next_node, + qubit_providing_node, qubit_providing_port); } else if gate == 'W' { break; // Ignoring global phases for now. + } else { + panic!("The gate {gate} is not supported") } } let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); // Assuming there were no outgoing ports to begin with when deciding port offset let src_port = ports[0]; hugr.connect(prev_node, src_port, next_node, dst_port); - println!("Inside panicking function: {}", hugr.mermaid_string()); + // println!("Inside panicking function: {}", hugr.mermaid_string()); hugr.validate().unwrap_or_else(|e| panic!("{e}")); } @@ -257,7 +268,7 @@ mod tests { let rz = h.add_dataflow_op(TketOp::Rz, [q_in, loaded_const]).unwrap(); let _ = h.set_outputs(rz.outputs()); let mut circ = h.finish_hugr().unwrap(); //(rz.outputs()).unwrap().into(); - println!("First mermaid string is: {}", circ.mermaid_string()); + // println!("First mermaid string is: {}", circ.mermaid_string()); circ.validate().unwrap_or_else(|e| panic!("{e}")); let rz_nodes = find_rzs(&mut circ).unwrap(); let rz_node = rz_nodes[0]; @@ -392,10 +403,11 @@ mod tests { // This test is just to check if a panic occurs let (mut circ, _) = build_rz_only_circ(); let epsilon: f64 = 1e-3; - // let gates = apply_gridsynth(&mut circ, epsilon); + // let rz_node = find_rzs(&mut circ).unwrap()[0]; + // let gates = apply_gridsynth(&mut circ, epsilon, rz_node); // println!("{}", &gates); apply_gridsynth_pass(&mut circ, epsilon); - // println!("{}", circ.mermaid_string()); + println!("{}", circ.mermaid_string()); } #[test] @@ -492,6 +504,8 @@ mod tests { let mut hugr = build_non_trivial_circ(); apply_gridsynth_pass(&mut hugr, epsilon); + // TO DO: FINISH by checking measurement results + // will need to run selene sim } #[test] @@ -501,6 +515,8 @@ mod tests { println!("before gridsynth: {}", hugr.mermaid_string()); apply_gridsynth_pass(&mut hugr, epsilon); + // TO DO: FINISH by checking measurement results + // Will need to run selene sim } } From 01a6c8477af70e4fc3dc56b794323a3248820895 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Fri, 19 Dec 2025 15:59:49 +0000 Subject: [PATCH 40/48] Removed experimental steps and debugging lines --- Cargo.lock | 334 ++++++++++++++++++++++++++++++++++- tket-py/test/test_pass.py | 20 +++ tket/src/passes/gridsynth.rs | 6 +- 3 files changed, 354 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ced60e00c..db88fe2fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,6 +109,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + [[package]] name = "arrayvec" version = "0.5.2" @@ -352,7 +361,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317" dependencies = [ - "approx", + "approx 0.4.0", "num-traits", "serde", ] @@ -707,6 +716,86 @@ dependencies = [ "rayon", ] +[[package]] +name = "dashu" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b3e5ac1e23ff1995ef05b912e2b012a8784506987a2651552db2c73fb3d7e0" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "dashu-macros", + "dashu-ratio", + "rustversion", +] + +[[package]] +name = "dashu-base" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b80bf6b85aa68c58ffea2ddb040109943049ce3fbdf4385d0380aef08ef289" + +[[package]] +name = "dashu-float" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85078445a8dbd2e1bd21f04a816f352db8d333643f0c9b78ca7c3d1df71063e7" +dependencies = [ + "dashu-base", + "dashu-int", + "num-modular", + "num-order", + "num-traits", + "rustversion", + "static_assertions", +] + +[[package]] +name = "dashu-int" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee99d08031ca34a4d044efbbb21dff9b8c54bb9d8c82a189187c0651ffdb9fbf" +dependencies = [ + "cfg-if", + "dashu-base", + "num-modular", + "num-order", + "num-traits", + "rustversion", + "static_assertions", +] + +[[package]] +name = "dashu-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93381c3ef6366766f6e9ed9cf09e4ef9dec69499baf04f0c60e70d653cf0ab10" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "dashu-ratio", + "paste", + "proc-macro2", + "quote", + "rustversion", +] + +[[package]] +name = "dashu-ratio" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e33b04dd7ce1ccf8a02a69d3419e354f2bbfdf4eb911a0b7465487248764c9" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "num-modular", + "num-order", + "rustversion", +] + [[package]] name = "delegate" version = "0.10.0" @@ -855,6 +944,29 @@ dependencies = [ "syn 2.0.108", ] +[[package]] +name = "env_filter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -1376,6 +1488,30 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jiff" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-static" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.108", +] + [[package]] name = "jobserver" version = "0.1.34" @@ -1452,6 +1588,16 @@ version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +[[package]] +name = "matrixmultiply" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" +dependencies = [ + "autocfg", + "rawpointer", +] + [[package]] name = "memchr" version = "2.7.6" @@ -1473,6 +1619,33 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "nalgebra" +version = "0.33.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" +dependencies = [ + "approx 0.5.1", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational", + "num-traits", + "simba", + "typenum", +] + +[[package]] +name = "nalgebra-macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.108", +] + [[package]] name = "nom" version = "7.1.3" @@ -1492,6 +1665,20 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -1502,6 +1689,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -1517,6 +1713,32 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-modular" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" + +[[package]] +name = "num-order" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" +dependencies = [ + "num-modular", +] + [[package]] name = "num-rational" version = "0.4.2" @@ -1572,7 +1794,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" dependencies = [ "num-traits", - "rand", + "rand 0.8.5", "serde", ] @@ -1735,6 +1957,15 @@ version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + [[package]] name = "portgraph" version = "0.8.0" @@ -1788,6 +2019,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + [[package]] name = "pretty" version = "0.12.5" @@ -1968,10 +2208,30 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "rand_core", + "rand_core 0.6.4", "serde", ] +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + [[package]] name = "rand_core" version = "0.6.4" @@ -1981,6 +2241,21 @@ dependencies = [ "serde", ] +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" version = "1.11.0" @@ -2103,6 +2378,26 @@ dependencies = [ "serde", ] +[[package]] +name = "rsgridsynth" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d7a6206ba19a3dbe199d9931a8630ce8b0f0c6cc393d81c700b8f2c8bd312fc" +dependencies = [ + "clap", + "dashu", + "dashu-base", + "dashu-float", + "dashu-int", + "env_logger", + "log", + "nalgebra", + "num", + "num-traits", + "once_cell", + "rand 0.9.2", +] + [[package]] name = "rstest" version = "0.26.1" @@ -2178,6 +2473,15 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "safe_arch" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" +dependencies = [ + "bytemuck", +] + [[package]] name = "same-file" version = "1.0.6" @@ -2380,6 +2684,19 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simba" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95" +dependencies = [ + "approx 0.5.1", + "num-complex", + "num-traits", + "paste", + "wide", +] + [[package]] name = "similar" version = "2.7.0" @@ -2674,6 +2991,7 @@ dependencies = [ "priority-queue", "rayon", "rmp-serde", + "rsgridsynth", "rstest", "serde", "serde_json", @@ -3077,6 +3395,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "wide" +version = "0.7.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" +dependencies = [ + "bytemuck", + "safe_arch", +] + [[package]] name = "winapi-util" version = "0.1.11" diff --git a/tket-py/test/test_pass.py b/tket-py/test/test_pass.py index 378550ada..7b9fe42e9 100644 --- a/tket-py/test/test_pass.py +++ b/tket-py/test/test_pass.py @@ -8,6 +8,7 @@ chunks, NormalizeGuppy, normalize_guppy, + # Gridsynth ) from tket.circuit import Tk2Circuit @@ -19,6 +20,8 @@ from tket.passes import PytketPass from pytket.passes import CliffordSimp, SquashRzPhasedX, SequencePass from hugr.build.base import Hugr +# from selene_sim import build, Quest +# from hugr.qsystem.result import QsysResult import pytest @@ -216,3 +219,20 @@ def test_normalize_guppy(): c2 = Tk2Circuit(pytket_circ) normal_circ2 = normalize_guppy(c2) assert normal_circ2.circuit_cost(lambda op: int(op == TketOp.CX)) == 3 + +# def test_gridsynth_pass(): +# alpha = 0.71 +# beta = 1.89 +# inverse_angle = - alpha - beta +# epsilon = 1e-2 + +# pytket_circ = Circuit(1).H(0).Rz(alpha, 0).Rz(beta, 0).Rz(inverse_angle, 0).H(0) +# circ = Tk2Circuit(pytket_circ) +# hugr = Hugr.from_str(circ.to_str()) +# gridsynth = Gridsynth(epsilon) +# gridsynth.run(hugr) +# runner = build(hugr, "test") +# shots = QsysResult( +# runner.run_shots(Quest(), n_qubits=1, n_shots=1)) + + diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 3cd878d89..0dda4e800 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -123,7 +123,7 @@ fn apply_gridsynth(hugr: &mut Hugr, epsilon: f64, rz_node: Node) -> String { let mut gridsynth_config = config_from_theta_epsilon(theta, epsilon, seed, verbose, up_to_phase); let gates = gridsynth_gates(&mut gridsynth_config); - println!("{}", gates.gates); + // println!("{}", gates.gates); gates.gates } @@ -457,8 +457,8 @@ mod tests { let rz_nodes = find_rzs(imported_hugr).unwrap(); let rz_node = rz_nodes[0]; let angle = find_angle(imported_hugr, rz_node); - println!("angle is {}", angle); - println!("hugr is {}", imported_hugr.mermaid_string()); + // println!("angle is {}", angle); + // println!("hugr is {}", imported_hugr.mermaid_string()); } #[test] From c6d272fb96024620cf1960190f47916fb9da8fa3 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Mon, 5 Jan 2026 13:27:22 +0000 Subject: [PATCH 41/48] Added garbage collection --- Cargo.lock | 10 +++ tket/src/passes/gridsynth.rs | 128 +++++++++++++++++++++++++++++------ 2 files changed, 119 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd41c9866..68c908575 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3400,6 +3400,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "wide" +version = "0.7.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" +dependencies = [ + "bytemuck", + "safe_arch", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 0dda4e800..8db30d33f 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -1,5 +1,7 @@ //! A pass that applies the gridsynth algorithm to all Rz gates in a HUGR. +use std::collections::HashMap; + use crate::extension::rotation::ConstRotation; use crate::hugr::hugr::hugrmut::HugrMut; use crate::hugr::HugrView; @@ -14,6 +16,56 @@ use hugr_core::OutgoingPort; use rsgridsynth::config::config_from_theta_epsilon; use rsgridsynth::gridsynth::gridsynth_gates; +/// Garbage collector for cleaning up constant nodes providing angles to the Rz gates and +/// all nodes on the path to them. +struct GarbageCollector{ + references: HashMap, // key: node index (of Const node containing angle), + // value: reference counter for that node + path: HashMap> // key: node index (of Const node containing angle), + // value: the nodes leading up to the constant node and the constant + // node itself + +} // CONCERN: I am concerned that this approach may not clean up properly if the Guppy user + // has redundant calls of the constant (eg, has used it to define another constant but then + // not used that constant). + +impl GarbageCollector { + /// Add references to constant node + fn add_references(&mut self, node: Node, increment: usize) { + // if reference not in references add it with the default value 1, else increment count + let count = self.references.entry(node.index()).or_insert(1); + *count += increment; + } + + /// Remove reference to a constant node + fn remove_references(&mut self, node: Node, increment: usize) { + // reduce reference count by 1 + let count = self.references.get_mut(&node.index()).unwrap(); + *count -= increment; + } + + /// Infer how many references there are to the angle-containing Const node + /// given the corresponding `load_const_node` + fn infer_references_to_angle(&mut self, hugr: &mut Hugr, load_const_node: Node, const_node: Node) { + let references_collection: Vec<_> = hugr.node_outputs(load_const_node).collect(); + let num_references = references_collection.len(); + // if reference not in references add it with the default value num_references, else do nothing + self.references.entry(const_node.index()).or_insert(num_references); + } + + /// If there are no references remaining to const_node, remove it and the nodes leading to it + fn collect(&mut self, hugr: &mut Hugr, const_node: Node) { + let node_index = &const_node.index(); + if self.references[node_index] <= 0 { + let path: Vec = self.path.get(node_index).unwrap().to_vec(); + for node in path { + hugr.remove_node(node); + } + } + } +} + + /// Find the nodes for the Rz gates. fn find_rzs(hugr: &mut Hugr) -> Option> { let mut rz_nodes: Vec = Vec::new(); @@ -56,43 +108,68 @@ fn find_single_linked_output_by_index( .expect("Not yet set-up to handle cases where there are no previous nodes") } + /// Find the constant node containing the angle to be inputted to the Rz gate. /// It is assumed that `hugr` has had the NormalizeGuppy passes applied to it /// prior to being applied. This function also cleans up behind itself removing /// everything on the path to the `angle_node` but not the `angle_node` itself, /// which is still needed. -fn find_angle_node(hugr: &mut Hugr, rz_node: Node) -> Node { +fn find_angle_node(hugr: &mut Hugr, rz_node: Node, garbage_collector: &mut GarbageCollector) -> Node { // find linked ports to the rz port where the angle will be inputted // the port offset of the angle is known to be 1 for the rz gate. let (mut prev_node, _) = find_single_linked_output_by_index(hugr, rz_node, 1); + // let mut prev_nodes: Vec = Vec::new(); // as all of the NormalizeGuppy passes have been run on the `hugr` before it enters this function, // and these passes include constant folding, we can assume that we can follow the 0th ports back // to a constant node where the angle is defined. let max_iterations = 10; let mut ii = 0; + let mut path = Vec::new(); // The nodes leading up to the angle_node and the angle_node + // itself loop { + // prev_nodes.push(prev_node); let (current_node, _) = find_single_linked_output_by_index(hugr, prev_node, 0); let op_type = hugr.get_optype(current_node); + path.push(current_node); + + garbage_collector.add_references(current_node, 1); + + // TO DO: update the following to apply additional checks that this is the angle node beyond + // just the fact it is a constant node if op_type.is_const() { - hugr.remove_node(prev_node); + // println!("The Rz node is: \n {}", rz_node.index()); + // println!("The prev_nodes are: {:?}", prev_nodes); + // println!("Just before for loop, HUGR is: \n {}", hugr.mermaid_string()); + // for node in prev_nodes { + // // println!("Inside for loop: \n {}", hugr.mermaid_string()); + // hugr.remove_node(node); + // } + let load_const_node = prev_node; let angle_node = current_node; + // Add references to angle node if this has not already been done + garbage_collector.infer_references_to_angle(hugr, load_const_node, angle_node); + // Remove one reference to reflect the fact that we are about to use the angle node + garbage_collector.remove_references(angle_node, 1); + // Let garbage collector know what nodes led to the angle node + garbage_collector.path.entry(angle_node.index()).or_insert(path); return angle_node; } if ii >= max_iterations { panic!("Angle finding failed"); // TO DO: improve error handling } - // Deleting all but nodes on the way to the rz_node but not the rz_node itself - hugr.remove_node(prev_node); + // Deleting all but nodes on the way to the angle containing node but not the rz_node itself + // hugr.remove_node(prev_node); // TO DO: garbage collect instead (probably do inside if statement above) + // garbage_collector.remove_references(prev_node, 1); prev_node = current_node; ii += 1; } } -fn find_angle(hugr: &mut Hugr, rz_node: Node) -> f64 { - let angle_node = find_angle_node(hugr, rz_node); +fn find_angle(hugr: &mut Hugr, rz_node: Node, garbage_collector: &mut GarbageCollector) -> f64 { + let angle_node = find_angle_node(hugr, rz_node, garbage_collector); let op_type = hugr.get_optype(angle_node); let angle_const = op_type.as_const().unwrap(); let angle_val = &angle_const.value; @@ -107,16 +184,16 @@ fn find_angle(hugr: &mut Hugr, rz_node: Node) -> f64 { panic!("Angle not specified as ConstRotation or ConstF64") }; - // we now have what we need to know from the angle node and can remove it from the hugr - hugr.remove_node(angle_node); + // we now have what we need to know from the angle node and can remove it from the hugr if + // no further references remain to it + garbage_collector.collect(hugr, angle_node); angle } -fn apply_gridsynth(hugr: &mut Hugr, epsilon: f64, rz_node: Node) -> String { - let theta = find_angle(hugr, rz_node); - // The following parameters could be made user-specifiable. For simplicity, I fix them, for now - // let epsilon = 1e-1; // very low precision to allow easier visualisation for demo +fn apply_gridsynth(hugr: &mut Hugr, epsilon: f64, rz_node: Node, + garbage_collector: &mut GarbageCollector) -> String { + let theta = find_angle(hugr, rz_node, garbage_collector); let seed = 1234; let verbose = false; let up_to_phase = false; @@ -169,7 +246,8 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) // getting node and output port that gave qubit to Rz gate let inputs: Vec<_> = hugr.node_inputs(rz_node).collect(); let input_port = inputs[0]; - let (qubit_providing_node, qubit_providing_port) = hugr.single_linked_output(rz_node, input_port).unwrap(); + let (qubit_providing_node, qubit_providing_port) = hugr + .single_linked_output(rz_node, input_port).unwrap(); let mut prev_node = qubit_providing_node.clone(); // find output port @@ -177,9 +255,10 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) let output_port = outputs[0]; let (next_node, dst_port) = hugr.single_linked_input(rz_node, output_port).unwrap(); - // we have now inferred what we need to know from the Rz node we are replacing and can remove it + // we have now inferred what we need to know from the Rz node we are replacing and can remove it ao hugr.remove_node(rz_node); + // println!("in panicking function: {}", hugr.mermaid_string()); // recursively adding next gate in gates to prev_node @@ -206,7 +285,7 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) // Assuming there were no outgoing ports to begin with when deciding port offset let src_port = ports[0]; hugr.connect(prev_node, src_port, next_node, dst_port); - // println!("Inside panicking function: {}", hugr.mermaid_string()); + // println!("Inside panicking function: \n {}", hugr.mermaid_string()); hugr.validate().unwrap_or_else(|e| panic!("{e}")); } @@ -222,9 +301,14 @@ pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) { .run(hugr) .unwrap(); + // println!("After normalize guppy the hugr is: \n {}", hugr.mermaid_string()); + let rz_nodes = find_rzs(hugr).unwrap(); + let mut garbage_collector = GarbageCollector{ + references: HashMap::new(), + path: HashMap::new()}; for node in rz_nodes { - let gates = apply_gridsynth(hugr, epsilon, node); + let gates = apply_gridsynth(hugr, epsilon, node, &mut garbage_collector); replace_rz_with_gridsynth_output(hugr, node, &gates); } } // TO DO: change name of this function to gridsynth @@ -437,9 +521,12 @@ mod tests { .inline_dfgs(true) .run(imported_hugr) .unwrap(); + let mut garbage_collector = GarbageCollector{ + references: HashMap::new(), + path: HashMap::new()}; let rz_nodes = find_rzs(imported_hugr).unwrap(); let rz_node = rz_nodes[0]; - let angle_node = find_angle_node(imported_hugr, rz_node); + let angle_node = find_angle_node(imported_hugr, rz_node, &mut garbage_collector); assert_eq!(angle_node.index(), 20); } @@ -454,9 +541,12 @@ mod tests { .inline_dfgs(true) .run(imported_hugr) .unwrap(); + let mut garbage_collector = GarbageCollector{ + references: HashMap::new(), + path: HashMap::new()}; let rz_nodes = find_rzs(imported_hugr).unwrap(); let rz_node = rz_nodes[0]; - let angle = find_angle(imported_hugr, rz_node); + let angle = find_angle(imported_hugr, rz_node, &mut garbage_collector); // println!("angle is {}", angle); // println!("hugr is {}", imported_hugr.mermaid_string()); } @@ -483,7 +573,7 @@ mod tests { fn test_2rzs_guppy_hugr() { let epsilon = 1e-2; let imported_hugr = &mut import_2rzs_guppy(); - println!("before: {}", imported_hugr.mermaid_string()); + // println!("before: {}", imported_hugr.mermaid_string()); NormalizeGuppy::default() .simplify_cfgs(true) .remove_tuple_untuple(true) From b5ac5b9998b68f11f2ec5282ed0f8fbaa68a0d09 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Tue, 6 Jan 2026 14:08:48 +0000 Subject: [PATCH 42/48] Cleaned up linting errors --- Cargo.toml | 4 - tket-py/Cargo.toml | 1 - tket/src/passes/gridsynth.rs | 199 ++++++++--------------------------- 3 files changed, 41 insertions(+), 163 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5932eecd8..6fd8eadca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,7 +102,3 @@ zstd = "0.13.3" anyhow = "1.0.100" num-rational = "0.4.2" rsgridsynth = "0.2.0" - -[profile.release.package.tket-py] -# Some configurations to reduce the size of tket wheels -strip = true diff --git a/tket-py/Cargo.toml b/tket-py/Cargo.toml index ed6303d6d..7d4e535c8 100644 --- a/tket-py/Cargo.toml +++ b/tket-py/Cargo.toml @@ -26,7 +26,6 @@ tket = { path = "../tket", version = "0.16.0", features = [ ] } tket-qsystem = { path = "../tket-qsystem", version = "0.22.0" } tket1-passes = { path = "../tket1-passes", version = "0.0.0" } - derive_more = { workspace = true, features = ["into", "from"] } hugr = { workspace = true } itertools = { workspace = true } diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 8db30d33f..a33a199c9 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -3,11 +3,11 @@ use std::collections::HashMap; use crate::extension::rotation::ConstRotation; -use crate::hugr::hugr::hugrmut::HugrMut; +use crate::hugr::hugr::{ValidationError, hugrmut::HugrMut}; use crate::hugr::HugrView; -use crate::hugr::{Node, Port}; +use crate::hugr::Node; use crate::hugr::NodeIndex; -use crate::passes::guppy::NormalizeGuppy; +use crate::passes::guppy::{NormalizeGuppy, NormalizeGuppyErrors}; use crate::TketOp; use crate::{hugr, op_matches, Hugr}; use hugr::algorithms::ComposablePass; @@ -16,6 +16,19 @@ use hugr_core::OutgoingPort; use rsgridsynth::config::config_from_theta_epsilon; use rsgridsynth::gridsynth::gridsynth_gates; +/// Errors that can occur during the Gridsynth pass due to acting on a hugr that +/// goes beyond the scope of what the pass can optimise. The most likely reasons for this +/// are that the Rz angle is defined at runtime or that the NormalizeGuppy pass is unable +/// to standardise the form of the HUGR enough. Issues may occur when the constant node +/// providing the angle crosses function boundaries or if the control flow is especially +/// complicated +#[derive(derive_more::Error, Debug, derive_more::Display, derive_more::From)] +pub enum GridsynthError { + /// Error during the NormalizeGuppy pass + NormalizeGuppyErrors(NormalizeGuppyErrors), + /// Error during validation of the HUGR + ValidationError(ValidationError) +} /// Garbage collector for cleaning up constant nodes providing angles to the Rz gates and /// all nodes on the path to them. struct GarbageCollector{ @@ -85,15 +98,6 @@ fn find_rzs(hugr: &mut Hugr) -> Option> { None } -// TO DO: extend this function to find all RZ gates - -fn find_linked_incoming_ports(hugr: &mut Hugr, node: Node, port_idx: usize) -> Vec<(Node, Port)> { - let ports = hugr.node_inputs(node); - let collected_ports: Vec<_> = ports.collect(); - let linked_ports = hugr.linked_ports(node, collected_ports[port_idx]); - let linked_ports: Vec<(Node, Port)> = linked_ports.collect(); - linked_ports -} /// find the output port and node linked to the input specified by `port_idz` for `node` fn find_single_linked_output_by_index( @@ -204,13 +208,6 @@ fn apply_gridsynth(hugr: &mut Hugr, epsilon: f64, rz_node: Node, gates.gates } -/// get previous node that provided qubit to Rz gate -fn find_qubit_source(hugr: &mut Hugr, rz_node: Node) -> Node { - let linked_ports = find_linked_incoming_ports(hugr, rz_node, 0); - - linked_ports[0].0 -} - /// Add a gridsynth gate to some previous node, which may or may not be a gridsynth gate, /// and connect fn add_gate_and_connect( @@ -242,7 +239,8 @@ fn add_gate_and_connect( } // TO DO: reduce number of arguments to this function. Six is too many. // I think that there must be a better way of doing this. -fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) { +fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) + -> Result<(), GridsynthError> { // getting node and output port that gave qubit to Rz gate let inputs: Vec<_> = hugr.node_inputs(rz_node).collect(); let input_port = inputs[0]; @@ -286,11 +284,13 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) let src_port = ports[0]; hugr.connect(prev_node, src_port, next_node, dst_port); // println!("Inside panicking function: \n {}", hugr.mermaid_string()); - hugr.validate().unwrap_or_else(|e| panic!("{e}")); + hugr.validate()?; + Ok(()) } /// Replace an Rz gate with the corresponding gates outputted by gridsynth -pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) { +pub fn apply_gridsynth_pass ( + hugr: &mut Hugr, epsilon: f64) -> Result<(), GridsynthError> { // Running passes to convert HUGR to standard form NormalizeGuppy::default() .simplify_cfgs(true) @@ -298,8 +298,7 @@ pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) { .constant_folding(true) .remove_dead_funcs(true) .inline_dfgs(true) - .run(hugr) - .unwrap(); + .run(hugr)?; // println!("After normalize guppy the hugr is: \n {}", hugr.mermaid_string()); @@ -309,8 +308,9 @@ pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) { path: HashMap::new()}; for node in rz_nodes { let gates = apply_gridsynth(hugr, epsilon, node, &mut garbage_collector); - replace_rz_with_gridsynth_output(hugr, node, &gates); + replace_rz_with_gridsynth_output(hugr, node, &gates)?; } + Ok(()) } // TO DO: change name of this function to gridsynth /// Example error. @@ -320,24 +320,20 @@ pub struct ExampleError { message: String, } -// Test of example function +// The following tests only check if any errors occur because Selene is challenging to access from the rust +// API. However, Selene simulations in Python versions of the HUGRs in these tests and more complicated HUGRS are +// available at https://github.com/Quantinuum/gridsynth_guppy_demo.git #[cfg(test)] mod tests { - use std::fs::File; - use std::io::BufReader; - use super::*; use crate::extension::rotation::ConstRotation; use crate::hugr::builder::{Container, DFGBuilder, Dataflow, HugrBuilder}; - use crate::hugr::envelope::read_described_envelope; use crate::extension::bool::bool_type; use crate::hugr::extension::prelude::{qb_t}; use crate::hugr::ops::Value; use crate::hugr::types::Signature; - use hugr::NodeIndex; use hugr::builder::DataflowHugr; - use hugr_core::std_extensions::std_reg; fn build_rz_only_circ() -> (Hugr, Node) { let theta = 0.64; @@ -402,7 +398,7 @@ mod tests { //println!("{}", builder.hugr().mermaid_string()); - let mut circ = builder.finish_hugr_with_outputs([meas_res]).unwrap_or_else(|e| panic!("{e}")); + let circ = builder.finish_hugr_with_outputs([meas_res]).unwrap_or_else(|e| panic!("{e}")); // let mut circ = builder.finish_hugr_with_outputs([q1, q2]).unwrap(); circ } @@ -459,154 +455,41 @@ mod tests { //println!("{}", builder.hugr().mermaid_string()); - let mut circ = builder.finish_hugr_with_outputs([meas_res1, meas_res2]).unwrap_or_else(|e| panic!("{e}")); + let circ = builder.finish_hugr_with_outputs([meas_res1, meas_res2]).unwrap_or_else(|e| panic!("{e}")); // let mut circ = builder.finish_hugr_with_outputs([q1, q2]).unwrap(); circ } - fn import_guppy(path: &'static str) -> Hugr { - let f = File::open(path).unwrap(); - let reader = BufReader::new(f); - let registry = std_reg(); - let (_, imported_package) = read_described_envelope(reader, ®istry).unwrap(); - - imported_package.modules[0].clone() - } - - fn import_rz_only_guppy_circuit() -> Hugr { - // TODO: update the following path - import_guppy("/home/kennycampbell/coding_projects/tket_gridsynth_ext/guppy_rz") - } - - fn import_2rzs_guppy() -> Hugr { - import_guppy("/home/kennycampbell/coding_projects/tket_gridsynth_ext/guppy_2Rzs") - } - #[test] fn gridsynth_pass_successful() { // This test is just to check if a panic occurs let (mut circ, _) = build_rz_only_circ(); let epsilon: f64 = 1e-3; - // let rz_node = find_rzs(&mut circ).unwrap()[0]; - // let gates = apply_gridsynth(&mut circ, epsilon, rz_node); - // println!("{}", &gates); - apply_gridsynth_pass(&mut circ, epsilon); - println!("{}", circ.mermaid_string()); - } - - #[test] - fn found_rz_guppy() { - let imported_hugr = &mut import_rz_only_guppy_circuit(); - NormalizeGuppy::default() - .simplify_cfgs(true) - .remove_tuple_untuple(true) - .constant_folding(true) - .remove_dead_funcs(true) - .inline_dfgs(true) - .run(imported_hugr) - .unwrap(); - let rz_nodes = find_rzs(imported_hugr).unwrap(); - let rz_node = rz_nodes[0]; - assert_eq!(rz_node.index(), 17) - } - - #[test] - fn test_find_angle_node_for_guppy() { - let imported_hugr = &mut import_rz_only_guppy_circuit(); - NormalizeGuppy::default() - .simplify_cfgs(true) - .remove_tuple_untuple(true) - .constant_folding(true) - .remove_dead_funcs(true) - .inline_dfgs(true) - .run(imported_hugr) - .unwrap(); - let mut garbage_collector = GarbageCollector{ - references: HashMap::new(), - path: HashMap::new()}; - let rz_nodes = find_rzs(imported_hugr).unwrap(); - let rz_node = rz_nodes[0]; - let angle_node = find_angle_node(imported_hugr, rz_node, &mut garbage_collector); - assert_eq!(angle_node.index(), 20); - } - - #[test] - fn test_find_angle_for_guppy() { - let imported_hugr = &mut import_rz_only_guppy_circuit(); - NormalizeGuppy::default() - .simplify_cfgs(true) - .remove_tuple_untuple(true) - .constant_folding(true) - .remove_dead_funcs(true) - .inline_dfgs(true) - .run(imported_hugr) - .unwrap(); - let mut garbage_collector = GarbageCollector{ - references: HashMap::new(), - path: HashMap::new()}; - let rz_nodes = find_rzs(imported_hugr).unwrap(); - let rz_node = rz_nodes[0]; - let angle = find_angle(imported_hugr, rz_node, &mut garbage_collector); - // println!("angle is {}", angle); - // println!("hugr is {}", imported_hugr.mermaid_string()); - } - - #[test] - fn test_with_guppy_hugr() { - let epsilon = 1e-2; - let imported_hugr = &mut import_rz_only_guppy_circuit(); - NormalizeGuppy::default() - .simplify_cfgs(true) - .remove_tuple_untuple(true) - .constant_folding(true) - .remove_dead_funcs(true) - .inline_dfgs(true) - .run(imported_hugr) - .unwrap(); - // constant_fold_pass(imported_hugr.as_mut()); - // println!("after {}", imported_hugr.mermaid_string()); - apply_gridsynth_pass(imported_hugr, epsilon); - println!("after: {}", imported_hugr.mermaid_string()); - } - - #[test] - fn test_2rzs_guppy_hugr() { - let epsilon = 1e-2; - let imported_hugr = &mut import_2rzs_guppy(); - // println!("before: {}", imported_hugr.mermaid_string()); - NormalizeGuppy::default() - .simplify_cfgs(true) - .remove_tuple_untuple(true) - .constant_folding(true) - .remove_dead_funcs(true) - .inline_dfgs(true) - .run(imported_hugr) - .unwrap(); - // constant_fold_pass(imported_hugr.as_mut()); - // println!("after {}", imported_hugr.mermaid_string()); - apply_gridsynth_pass(imported_hugr, epsilon); - println!("after: {}", imported_hugr.mermaid_string()); + apply_gridsynth_pass(&mut circ, epsilon).unwrap(); } #[test] fn test_non_trivial_circ_1qubit() { + // Due to challenge of accessing Selene from rust, this just + // tests for if errors occur. It would be nice to have a call to + // Selene here. (See https://github.com/Quantinuum/gridsynth_guppy_demo.git for a Python example + // of this circuit working) let epsilon = 1e-2; let mut hugr = build_non_trivial_circ(); - apply_gridsynth_pass(&mut hugr, epsilon); - // TO DO: FINISH by checking measurement results - // will need to run selene sim + apply_gridsynth_pass(&mut hugr, epsilon).unwrap(); } #[test] fn test_non_trivial_circ_2qubits() { + // Due to challenge of accessing Selene from rust, this just + // tests for if errors occur. It would be nice to have a call to + // Selene here. (See https://github.com/Quantinuum/gridsynth_guppy_demo.git for a Python example + // of this circuit working) let epsilon = 1e-2; let mut hugr = build_non_trivial_circ_2qubits(); println!("before gridsynth: {}", hugr.mermaid_string()); - apply_gridsynth_pass(&mut hugr, epsilon); - // TO DO: FINISH by checking measurement results - // Will need to run selene sim - + apply_gridsynth_pass(&mut hugr, epsilon).unwrap(); } } From b0fe8652334da593937fea117ce607f46a28fbca Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Tue, 6 Jan 2026 14:39:41 +0000 Subject: [PATCH 43/48] just check passing --- tket-py/src/passes/gridsynth.rs | 14 +- tket-py/test/test_pass.py | 3 +- tket/src/passes/gridsynth.rs | 244 +++++++++++++++++++------------- 3 files changed, 158 insertions(+), 103 deletions(-) diff --git a/tket-py/src/passes/gridsynth.rs b/tket-py/src/passes/gridsynth.rs index b44ed6112..386635989 100644 --- a/tket-py/src/passes/gridsynth.rs +++ b/tket-py/src/passes/gridsynth.rs @@ -1,11 +1,18 @@ //! Bindings to allow users to access the gridsynth pass from Python. //! The definitions here should be reflected in the //! `tket-py/tket/_tket/passes.pyi` type stubs file -use crate::circuit::try_with_circ; use crate::circuit::CircuitType; +use crate::circuit::try_with_circ; +use crate::utils::{ConvertPyErr, create_py_exception}; use pyo3::prelude::*; use tket::passes::gridsynth::apply_gridsynth_pass; +create_py_exception!( + tket::passes::gridsynth::GridsynthError, + PyGridsynthError, + "Errors from the gridsynth pass." +); + /// Binding to a python function called gridsynth that runs the rust function called /// apply_gridsynth pass behind the scenes #[pyfunction] @@ -13,12 +20,9 @@ pub fn gridsynth<'py>(circ: &Bound<'py, PyAny>, epsilon: f64) -> PyResult) + ValidationError(ValidationError), } -/// Garbage collector for cleaning up constant nodes providing angles to the Rz gates and +/// Garbage collector for cleaning up constant nodes providing angles to the Rz gates and /// all nodes on the path to them. -struct GarbageCollector{ +struct GarbageCollector { references: HashMap, // key: node index (of Const node containing angle), - // value: reference counter for that node - path: HashMap> // key: node index (of Const node containing angle), - // value: the nodes leading up to the constant node and the constant - // node itself - -} // CONCERN: I am concerned that this approach may not clean up properly if the Guppy user - // has redundant calls of the constant (eg, has used it to define another constant but then - // not used that constant). + // value: reference counter for that node + path: HashMap>, // key: node index (of Const node containing angle), + // value: the nodes leading up to the constant node and the constant + // node itself +} // CONCERN: I am concerned that this approach may not clean up properly if the Guppy user +// has redundant calls of the constant (eg, has used it to define another constant but then +// not used that constant). impl GarbageCollector { /// Add references to constant node @@ -59,26 +58,32 @@ impl GarbageCollector { /// Infer how many references there are to the angle-containing Const node /// given the corresponding `load_const_node` - fn infer_references_to_angle(&mut self, hugr: &mut Hugr, load_const_node: Node, const_node: Node) { + fn infer_references_to_angle( + &mut self, + hugr: &mut Hugr, + load_const_node: Node, + const_node: Node, + ) { let references_collection: Vec<_> = hugr.node_outputs(load_const_node).collect(); let num_references = references_collection.len(); // if reference not in references add it with the default value num_references, else do nothing - self.references.entry(const_node.index()).or_insert(num_references); + self.references + .entry(const_node.index()) + .or_insert(num_references); } /// If there are no references remaining to const_node, remove it and the nodes leading to it fn collect(&mut self, hugr: &mut Hugr, const_node: Node) { let node_index = &const_node.index(); - if self.references[node_index] <= 0 { - let path: Vec = self.path.get(node_index).unwrap().to_vec(); - for node in path { + if self.references[node_index] == 0 { + let path: Vec = self.path.get(node_index).unwrap().to_vec(); + for node in path { hugr.remove_node(node); - } + } } } } - /// Find the nodes for the Rz gates. fn find_rzs(hugr: &mut Hugr) -> Option> { let mut rz_nodes: Vec = Vec::new(); @@ -98,7 +103,6 @@ fn find_rzs(hugr: &mut Hugr) -> Option> { None } - /// find the output port and node linked to the input specified by `port_idz` for `node` fn find_single_linked_output_by_index( hugr: &mut Hugr, @@ -112,13 +116,16 @@ fn find_single_linked_output_by_index( .expect("Not yet set-up to handle cases where there are no previous nodes") } - /// Find the constant node containing the angle to be inputted to the Rz gate. /// It is assumed that `hugr` has had the NormalizeGuppy passes applied to it /// prior to being applied. This function also cleans up behind itself removing /// everything on the path to the `angle_node` but not the `angle_node` itself, /// which is still needed. -fn find_angle_node(hugr: &mut Hugr, rz_node: Node, garbage_collector: &mut GarbageCollector) -> Node { +fn find_angle_node( + hugr: &mut Hugr, + rz_node: Node, + garbage_collector: &mut GarbageCollector, +) -> Node { // find linked ports to the rz port where the angle will be inputted // the port offset of the angle is known to be 1 for the rz gate. let (mut prev_node, _) = find_single_linked_output_by_index(hugr, rz_node, 1); @@ -129,8 +136,8 @@ fn find_angle_node(hugr: &mut Hugr, rz_node: Node, garbage_collector: &mut Garba // to a constant node where the angle is defined. let max_iterations = 10; let mut ii = 0; - let mut path = Vec::new(); // The nodes leading up to the angle_node and the angle_node - // itself + let mut path = Vec::new(); // The nodes leading up to the angle_node and the angle_node + // itself loop { // prev_nodes.push(prev_node); let (current_node, _) = find_single_linked_output_by_index(hugr, prev_node, 0); @@ -156,7 +163,10 @@ fn find_angle_node(hugr: &mut Hugr, rz_node: Node, garbage_collector: &mut Garba // Remove one reference to reflect the fact that we are about to use the angle node garbage_collector.remove_references(angle_node, 1); // Let garbage collector know what nodes led to the angle node - garbage_collector.path.entry(angle_node.index()).or_insert(path); + garbage_collector + .path + .entry(angle_node.index()) + .or_insert(path); return angle_node; } if ii >= max_iterations { @@ -188,15 +198,19 @@ fn find_angle(hugr: &mut Hugr, rz_node: Node, garbage_collector: &mut GarbageCol panic!("Angle not specified as ConstRotation or ConstF64") }; - // we now have what we need to know from the angle node and can remove it from the hugr if + // we now have what we need to know from the angle node and can remove it from the hugr if // no further references remain to it garbage_collector.collect(hugr, angle_node); angle } -fn apply_gridsynth(hugr: &mut Hugr, epsilon: f64, rz_node: Node, - garbage_collector: &mut GarbageCollector) -> String { +fn apply_gridsynth( + hugr: &mut Hugr, + epsilon: f64, + rz_node: Node, + garbage_collector: &mut GarbageCollector, +) -> String { let theta = find_angle(hugr, rz_node, garbage_collector); let seed = 1234; let verbose = false; @@ -211,22 +225,21 @@ fn apply_gridsynth(hugr: &mut Hugr, epsilon: f64, rz_node: Node, /// Add a gridsynth gate to some previous node, which may or may not be a gridsynth gate, /// and connect fn add_gate_and_connect( - hugr: &mut Hugr, + hugr: &mut Hugr, prev_node: Node, op: hugr::ops::OpType, output_node: Node, qubit_providing_node: Node, // the node providing qubit to Rz gate - qubit_providing_port: OutgoingPort // the output port providing qubit to Rz gate + qubit_providing_port: OutgoingPort, // the output port providing qubit to Rz gate ) -> Node { let current_node = hugr.add_node_after(output_node, op); let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); - // if the previous node was the qubit_providing_node then it could have multiple + // if the previous node was the qubit_providing_node then it could have multiple // outputs (eg, if multi-qubit gate and so need to be explicit about port) let src_port = if prev_node.index() == qubit_providing_node.index() { qubit_providing_port - } - else { + } else { // the ops generated by gridsynth are all single input single output gates, so // it is safe to assume that there is only one output port ports[0] @@ -237,16 +250,19 @@ fn add_gate_and_connect( current_node } // TO DO: reduce number of arguments to this function. Six is too many. - // I think that there must be a better way of doing this. +// I think that there must be a better way of doing this. -fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) - -> Result<(), GridsynthError> { +fn replace_rz_with_gridsynth_output( + hugr: &mut Hugr, + rz_node: Node, + gates: &str, +) -> Result<(), GridsynthError> { // getting node and output port that gave qubit to Rz gate let inputs: Vec<_> = hugr.node_inputs(rz_node).collect(); let input_port = inputs[0]; - let (qubit_providing_node, qubit_providing_port) = hugr - .single_linked_output(rz_node, input_port).unwrap(); - let mut prev_node = qubit_providing_node.clone(); + let (qubit_providing_node, qubit_providing_port) = + hugr.single_linked_output(rz_node, input_port).unwrap(); + let mut prev_node = qubit_providing_node; // find output port let outputs: Vec<_> = hugr.node_outputs(rz_node).collect(); @@ -256,23 +272,46 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) // we have now inferred what we need to know from the Rz node we are replacing and can remove it ao hugr.remove_node(rz_node); - // println!("in panicking function: {}", hugr.mermaid_string()); // recursively adding next gate in gates to prev_node for gate in gates.chars() { if gate == 'H' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::H.into(), next_node, - qubit_providing_node, qubit_providing_port); + prev_node = add_gate_and_connect( + hugr, + prev_node, + TketOp::H.into(), + next_node, + qubit_providing_node, + qubit_providing_port, + ); } else if gate == 'S' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::S.into(), next_node, - qubit_providing_node, qubit_providing_port); + prev_node = add_gate_and_connect( + hugr, + prev_node, + TketOp::S.into(), + next_node, + qubit_providing_node, + qubit_providing_port, + ); } else if gate == 'T' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::T.into(), next_node, - qubit_providing_node, qubit_providing_port); + prev_node = add_gate_and_connect( + hugr, + prev_node, + TketOp::T.into(), + next_node, + qubit_providing_node, + qubit_providing_port, + ); } else if gate == 'X' { - prev_node = add_gate_and_connect(hugr, prev_node, TketOp::X.into(), next_node, - qubit_providing_node, qubit_providing_port); + prev_node = add_gate_and_connect( + hugr, + prev_node, + TketOp::X.into(), + next_node, + qubit_providing_node, + qubit_providing_port, + ); } else if gate == 'W' { break; // Ignoring global phases for now. } else { @@ -281,7 +320,7 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) } let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); // Assuming there were no outgoing ports to begin with when deciding port offset - let src_port = ports[0]; + let src_port = ports[0]; hugr.connect(prev_node, src_port, next_node, dst_port); // println!("Inside panicking function: \n {}", hugr.mermaid_string()); hugr.validate()?; @@ -289,8 +328,7 @@ fn replace_rz_with_gridsynth_output(hugr: &mut Hugr, rz_node: Node, gates: &str) } /// Replace an Rz gate with the corresponding gates outputted by gridsynth -pub fn apply_gridsynth_pass ( - hugr: &mut Hugr, epsilon: f64) -> Result<(), GridsynthError> { +pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) -> Result<(), GridsynthError> { // Running passes to convert HUGR to standard form NormalizeGuppy::default() .simplify_cfgs(true) @@ -303,9 +341,10 @@ pub fn apply_gridsynth_pass ( // println!("After normalize guppy the hugr is: \n {}", hugr.mermaid_string()); let rz_nodes = find_rzs(hugr).unwrap(); - let mut garbage_collector = GarbageCollector{ - references: HashMap::new(), - path: HashMap::new()}; + let mut garbage_collector = GarbageCollector { + references: HashMap::new(), + path: HashMap::new(), + }; for node in rz_nodes { let gates = apply_gridsynth(hugr, epsilon, node, &mut garbage_collector); replace_rz_with_gridsynth_output(hugr, node, &gates)?; @@ -320,17 +359,17 @@ pub struct ExampleError { message: String, } -// The following tests only check if any errors occur because Selene is challenging to access from the rust +// The following tests only check if any errors occur because Selene is challenging to access from the rust // API. However, Selene simulations in Python versions of the HUGRs in these tests and more complicated HUGRS are -// available at https://github.com/Quantinuum/gridsynth_guppy_demo.git +// available at https://github.com/Quantinuum/gridsynth_guppy_demo.git #[cfg(test)] mod tests { use super::*; + use crate::extension::bool::bool_type; use crate::extension::rotation::ConstRotation; use crate::hugr::builder::{Container, DFGBuilder, Dataflow, HugrBuilder}; - use crate::extension::bool::bool_type; - use crate::hugr::extension::prelude::{qb_t}; + use crate::hugr::extension::prelude::qb_t; use crate::hugr::ops::Value; use crate::hugr::types::Signature; use hugr::builder::DataflowHugr; @@ -354,17 +393,18 @@ mod tests { let rz_node = rz_nodes[0]; (circ, rz_node) } - + fn build_non_trivial_circ() -> Hugr { // defining some angles for Rz gates in radians let alpha = 0.23; let beta = 1.78; - let inverse_angle = - alpha - beta; + let inverse_angle = -alpha - beta; // defining builder for circuit - let qb_row= vec![qb_t(); 1]; + let qb_row = vec![qb_t(); 1]; let meas_row = vec![bool_type(); 1]; - let mut builder = DFGBuilder::new(Signature::new(qb_row.clone(), meas_row.clone())).unwrap(); + let mut builder = + DFGBuilder::new(Signature::new(qb_row.clone(), meas_row.clone())).unwrap(); let [q1] = builder.input_wires_arr(); // adding constant wires and nodes @@ -372,47 +412,52 @@ mod tests { ConstRotation::from_radians(alpha).unwrap(), )); let loaded_alpha = builder.load_const(&alpha_const); - let beta_const = builder.add_constant(Value::extension( - ConstRotation::from_radians(beta).unwrap(), - )); + let beta_const = + builder.add_constant(Value::extension(ConstRotation::from_radians(beta).unwrap())); let loaded_beta = builder.load_const(&beta_const); let inverse_const = builder.add_constant(Value::extension( ConstRotation::from_radians(inverse_angle).unwrap(), )); - let loaded_inverse = builder.load_const(&inverse_const); + let loaded_inverse = builder.load_const(&inverse_const); // adding gates and measurements let had1 = builder.add_dataflow_op(TketOp::H, [q1]).unwrap(); let [q1] = had1.outputs_arr(); - let rz_alpha = builder.add_dataflow_op(TketOp::Rz, [q1, loaded_alpha]).unwrap(); + let rz_alpha = builder + .add_dataflow_op(TketOp::Rz, [q1, loaded_alpha]) + .unwrap(); let [q1] = rz_alpha.outputs_arr(); - let rz_beta = builder.add_dataflow_op(TketOp::Rz, [q1, loaded_beta]).unwrap(); + let rz_beta = builder + .add_dataflow_op(TketOp::Rz, [q1, loaded_beta]) + .unwrap(); let [q1] = rz_beta.outputs_arr(); - let rz_inverse = builder.add_dataflow_op(TketOp::Rz, [q1, loaded_inverse]).unwrap(); + let rz_inverse = builder + .add_dataflow_op(TketOp::Rz, [q1, loaded_inverse]) + .unwrap(); let [q1] = rz_inverse.outputs_arr(); let had2 = builder.add_dataflow_op(TketOp::H, [q1]).unwrap(); let [q1] = had2.outputs_arr(); - let meas_res = builder.add_dataflow_op(TketOp::MeasureFree, [q1]) + let meas_res = builder + .add_dataflow_op(TketOp::MeasureFree, [q1]) .unwrap() .out_wire(0); - //println!("{}", builder.hugr().mermaid_string()); - - let circ = builder.finish_hugr_with_outputs([meas_res]).unwrap_or_else(|e| panic!("{e}")); - // let mut circ = builder.finish_hugr_with_outputs([q1, q2]).unwrap(); - circ + builder + .finish_hugr_with_outputs([meas_res]) + .unwrap_or_else(|e| panic!("{e}")) } fn build_non_trivial_circ_2qubits() -> Hugr { // defining some angles for Rz gates in radians let alpha = 0.23; let beta = 1.78; - let inverse_angle = - alpha - beta; + let inverse_angle = -alpha - beta; // defining builder for circuit - let qb_row= vec![qb_t(); 2]; + let qb_row = vec![qb_t(); 2]; let meas_row = vec![bool_type(); 2]; - let mut builder = DFGBuilder::new(Signature::new(qb_row.clone(), meas_row.clone())).unwrap(); + let mut builder = + DFGBuilder::new(Signature::new(qb_row.clone(), meas_row.clone())).unwrap(); let [q1, q2] = builder.input_wires_arr(); // adding constant wires and nodes @@ -420,44 +465,51 @@ mod tests { ConstRotation::from_radians(alpha).unwrap(), )); let loaded_alpha = builder.load_const(&alpha_const); - let beta_const = builder.add_constant(Value::extension( - ConstRotation::from_radians(beta).unwrap(), - )); + let beta_const = + builder.add_constant(Value::extension(ConstRotation::from_radians(beta).unwrap())); let loaded_beta = builder.load_const(&beta_const); let inverse_const = builder.add_constant(Value::extension( ConstRotation::from_radians(inverse_angle).unwrap(), )); - let loaded_inverse = builder.load_const(&inverse_const); + let loaded_inverse = builder.load_const(&inverse_const); // adding gates and measurements let had1 = builder.add_dataflow_op(TketOp::H, [q1]).unwrap(); let [q1] = had1.outputs_arr(); - let rz_alpha = builder.add_dataflow_op(TketOp::Rz, [q1, loaded_alpha]).unwrap(); + let rz_alpha = builder + .add_dataflow_op(TketOp::Rz, [q1, loaded_alpha]) + .unwrap(); let [q1] = rz_alpha.outputs_arr(); - let rz_beta = builder.add_dataflow_op(TketOp::Rz, [q1, loaded_beta]).unwrap(); + let rz_beta = builder + .add_dataflow_op(TketOp::Rz, [q1, loaded_beta]) + .unwrap(); let [q1] = rz_beta.outputs_arr(); let x = builder.add_dataflow_op(TketOp::X, [q2]).unwrap(); let [q2] = x.outputs_arr(); let cx1 = builder.add_dataflow_op(TketOp::CX, [q2, q1]).unwrap(); let [q2, q1] = cx1.outputs_arr(); - let rz_inverse = builder.add_dataflow_op(TketOp::Rz, [q1, loaded_inverse]).unwrap(); + let rz_inverse = builder + .add_dataflow_op(TketOp::Rz, [q1, loaded_inverse]) + .unwrap(); let [q1] = rz_inverse.outputs_arr(); let cx2 = builder.add_dataflow_op(TketOp::CX, [q2, q1]).unwrap(); let [q2, q1] = cx2.outputs_arr(); let had2 = builder.add_dataflow_op(TketOp::H, [q1]).unwrap(); let [q1] = had2.outputs_arr(); - let meas_res1 = builder.add_dataflow_op(TketOp::MeasureFree, [q1]) + let meas_res1 = builder + .add_dataflow_op(TketOp::MeasureFree, [q1]) .unwrap() .out_wire(0); - let meas_res2 = builder.add_dataflow_op(TketOp::MeasureFree, [q2]) + let meas_res2 = builder + .add_dataflow_op(TketOp::MeasureFree, [q2]) .unwrap() .out_wire(0); //println!("{}", builder.hugr().mermaid_string()); - let circ = builder.finish_hugr_with_outputs([meas_res1, meas_res2]).unwrap_or_else(|e| panic!("{e}")); - // let mut circ = builder.finish_hugr_with_outputs([q1, q2]).unwrap(); - circ + builder + .finish_hugr_with_outputs([meas_res1, meas_res2]) + .unwrap_or_else(|e| panic!("{e}")) } #[test] @@ -470,7 +522,7 @@ mod tests { #[test] fn test_non_trivial_circ_1qubit() { - // Due to challenge of accessing Selene from rust, this just + // Due to challenge of accessing Selene from rust, this just // tests for if errors occur. It would be nice to have a call to // Selene here. (See https://github.com/Quantinuum/gridsynth_guppy_demo.git for a Python example // of this circuit working) @@ -482,7 +534,7 @@ mod tests { #[test] fn test_non_trivial_circ_2qubits() { - // Due to challenge of accessing Selene from rust, this just + // Due to challenge of accessing Selene from rust, this just // tests for if errors occur. It would be nice to have a call to // Selene here. (See https://github.com/Quantinuum/gridsynth_guppy_demo.git for a Python example // of this circuit working) From 3cb63c5b1b947df68baaf154a50664c5280c0479 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Tue, 6 Jan 2026 14:51:32 +0000 Subject: [PATCH 44/48] Tidied comments --- tket/src/passes/gridsynth.rs | 64 +++++++++++------------------------- 1 file changed, 19 insertions(+), 45 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 6d368477d..dbaf192f2 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -103,7 +103,7 @@ fn find_rzs(hugr: &mut Hugr) -> Option> { None } -/// find the output port and node linked to the input specified by `port_idz` for `node` +/// Find the output port and node linked to the input specified by `port_idz` for `node` fn find_single_linked_output_by_index( hugr: &mut Hugr, node: Node, @@ -126,12 +126,11 @@ fn find_angle_node( rz_node: Node, garbage_collector: &mut GarbageCollector, ) -> Node { - // find linked ports to the rz port where the angle will be inputted + // Find linked ports to the rz port where the angle will be inputted // the port offset of the angle is known to be 1 for the rz gate. let (mut prev_node, _) = find_single_linked_output_by_index(hugr, rz_node, 1); - // let mut prev_nodes: Vec = Vec::new(); - // as all of the NormalizeGuppy passes have been run on the `hugr` before it enters this function, + // As all of the NormalizeGuppy passes have been run on the `hugr` before it enters this function, // and these passes include constant folding, we can assume that we can follow the 0th ports back // to a constant node where the angle is defined. let max_iterations = 10; @@ -139,23 +138,13 @@ fn find_angle_node( let mut path = Vec::new(); // The nodes leading up to the angle_node and the angle_node // itself loop { - // prev_nodes.push(prev_node); let (current_node, _) = find_single_linked_output_by_index(hugr, prev_node, 0); let op_type = hugr.get_optype(current_node); path.push(current_node); garbage_collector.add_references(current_node, 1); - // TO DO: update the following to apply additional checks that this is the angle node beyond - // just the fact it is a constant node if op_type.is_const() { - // println!("The Rz node is: \n {}", rz_node.index()); - // println!("The prev_nodes are: {:?}", prev_nodes); - // println!("Just before for loop, HUGR is: \n {}", hugr.mermaid_string()); - // for node in prev_nodes { - // // println!("Inside for loop: \n {}", hugr.mermaid_string()); - // hugr.remove_node(node); - // } let load_const_node = prev_node; let angle_node = current_node; // Add references to angle node if this has not already been done @@ -170,13 +159,9 @@ fn find_angle_node( return angle_node; } if ii >= max_iterations { - panic!("Angle finding failed"); // TO DO: improve error handling + panic!("Angle finding failed"); } - // Deleting all but nodes on the way to the angle containing node but not the rz_node itself - // hugr.remove_node(prev_node); // TO DO: garbage collect instead (probably do inside if statement above) - // garbage_collector.remove_references(prev_node, 1); - prev_node = current_node; ii += 1; } @@ -188,7 +173,7 @@ fn find_angle(hugr: &mut Hugr, rz_node: Node, garbage_collector: &mut GarbageCol let angle_const = op_type.as_const().unwrap(); let angle_val = &angle_const.value; - // handling likely angle formats. Panic if angle is not one of the anticipated formats + // Handling likely angle formats. Panic if angle is not one of the anticipated formats let angle = if let Some(rot) = angle_val.get_custom_value::() { rot.to_radians() } else if let Some(fl) = angle_val.get_custom_value::() { @@ -198,7 +183,7 @@ fn find_angle(hugr: &mut Hugr, rz_node: Node, garbage_collector: &mut GarbageCol panic!("Angle not specified as ConstRotation or ConstF64") }; - // we now have what we need to know from the angle node and can remove it from the hugr if + // We now have what we need to know from the angle node and can remove it from the HUGR if // no further references remain to it garbage_collector.collect(hugr, angle_node); @@ -218,7 +203,6 @@ fn apply_gridsynth( let mut gridsynth_config = config_from_theta_epsilon(theta, epsilon, seed, verbose, up_to_phase); let gates = gridsynth_gates(&mut gridsynth_config); - // println!("{}", gates.gates); gates.gates } @@ -229,13 +213,13 @@ fn add_gate_and_connect( prev_node: Node, op: hugr::ops::OpType, output_node: Node, - qubit_providing_node: Node, // the node providing qubit to Rz gate - qubit_providing_port: OutgoingPort, // the output port providing qubit to Rz gate + qubit_providing_node: Node, // The node providing qubit to Rz gate + qubit_providing_port: OutgoingPort, // The output port providing qubit to Rz gate ) -> Node { let current_node = hugr.add_node_after(output_node, op); let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); - // if the previous node was the qubit_providing_node then it could have multiple + // If the previous node was the qubit_providing_node then it could have multiple // outputs (eg, if multi-qubit gate and so need to be explicit about port) let src_port = if prev_node.index() == qubit_providing_node.index() { qubit_providing_port @@ -250,7 +234,6 @@ fn add_gate_and_connect( current_node } // TO DO: reduce number of arguments to this function. Six is too many. -// I think that there must be a better way of doing this. fn replace_rz_with_gridsynth_output( hugr: &mut Hugr, @@ -272,8 +255,6 @@ fn replace_rz_with_gridsynth_output( // we have now inferred what we need to know from the Rz node we are replacing and can remove it ao hugr.remove_node(rz_node); - // println!("in panicking function: {}", hugr.mermaid_string()); - // recursively adding next gate in gates to prev_node for gate in gates.chars() { if gate == 'H' { @@ -322,7 +303,6 @@ fn replace_rz_with_gridsynth_output( // Assuming there were no outgoing ports to begin with when deciding port offset let src_port = ports[0]; hugr.connect(prev_node, src_port, next_node, dst_port); - // println!("Inside panicking function: \n {}", hugr.mermaid_string()); hugr.validate()?; Ok(()) } @@ -338,8 +318,6 @@ pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) -> Result<(), Gridsyn .inline_dfgs(true) .run(hugr)?; - // println!("After normalize guppy the hugr is: \n {}", hugr.mermaid_string()); - let rz_nodes = find_rzs(hugr).unwrap(); let mut garbage_collector = GarbageCollector { references: HashMap::new(), @@ -350,7 +328,7 @@ pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) -> Result<(), Gridsyn replace_rz_with_gridsynth_output(hugr, node, &gates)?; } Ok(()) -} // TO DO: change name of this function to gridsynth +} /// Example error. #[derive(Debug, derive_more::Display, derive_more::Error)] @@ -386,8 +364,7 @@ mod tests { let loaded_const = h.load_const(&constant); let rz = h.add_dataflow_op(TketOp::Rz, [q_in, loaded_const]).unwrap(); let _ = h.set_outputs(rz.outputs()); - let mut circ = h.finish_hugr().unwrap(); //(rz.outputs()).unwrap().into(); - // println!("First mermaid string is: {}", circ.mermaid_string()); + let mut circ = h.finish_hugr().unwrap(); circ.validate().unwrap_or_else(|e| panic!("{e}")); let rz_nodes = find_rzs(&mut circ).unwrap(); let rz_node = rz_nodes[0]; @@ -395,19 +372,19 @@ mod tests { } fn build_non_trivial_circ() -> Hugr { - // defining some angles for Rz gates in radians + // Defining some angles for Rz gates in radians let alpha = 0.23; let beta = 1.78; let inverse_angle = -alpha - beta; - // defining builder for circuit + // Defining builder for circuit let qb_row = vec![qb_t(); 1]; let meas_row = vec![bool_type(); 1]; let mut builder = DFGBuilder::new(Signature::new(qb_row.clone(), meas_row.clone())).unwrap(); let [q1] = builder.input_wires_arr(); - // adding constant wires and nodes + // Adding constant wires and nodes let alpha_const = builder.add_constant(Value::extension( ConstRotation::from_radians(alpha).unwrap(), )); @@ -420,7 +397,7 @@ mod tests { )); let loaded_inverse = builder.load_const(&inverse_const); - // adding gates and measurements + // Adding gates and measurements let had1 = builder.add_dataflow_op(TketOp::H, [q1]).unwrap(); let [q1] = had1.outputs_arr(); let rz_alpha = builder @@ -448,19 +425,19 @@ mod tests { } fn build_non_trivial_circ_2qubits() -> Hugr { - // defining some angles for Rz gates in radians + // Defining some angles for Rz gates in radians let alpha = 0.23; let beta = 1.78; let inverse_angle = -alpha - beta; - // defining builder for circuit + // Defining builder for circuit let qb_row = vec![qb_t(); 2]; let meas_row = vec![bool_type(); 2]; let mut builder = DFGBuilder::new(Signature::new(qb_row.clone(), meas_row.clone())).unwrap(); let [q1, q2] = builder.input_wires_arr(); - // adding constant wires and nodes + // Adding constant wires and nodes let alpha_const = builder.add_constant(Value::extension( ConstRotation::from_radians(alpha).unwrap(), )); @@ -473,7 +450,7 @@ mod tests { )); let loaded_inverse = builder.load_const(&inverse_const); - // adding gates and measurements + // Adding gates and measurements let had1 = builder.add_dataflow_op(TketOp::H, [q1]).unwrap(); let [q1] = had1.outputs_arr(); let rz_alpha = builder @@ -505,8 +482,6 @@ mod tests { .unwrap() .out_wire(0); - //println!("{}", builder.hugr().mermaid_string()); - builder .finish_hugr_with_outputs([meas_res1, meas_res2]) .unwrap_or_else(|e| panic!("{e}")) @@ -540,7 +515,6 @@ mod tests { // of this circuit working) let epsilon = 1e-2; let mut hugr = build_non_trivial_circ_2qubits(); - println!("before gridsynth: {}", hugr.mermaid_string()); apply_gridsynth_pass(&mut hugr, epsilon).unwrap(); } From a89c81bbf017e4291587f517047722fee6e75643 Mon Sep 17 00:00:00 2001 From: Kenny Campbell Date: Tue, 6 Jan 2026 15:35:22 +0000 Subject: [PATCH 45/48] Removed commented out code --- tket-py/test/test_pass.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/tket-py/test/test_pass.py b/tket-py/test/test_pass.py index b99c38484..9dd673c34 100644 --- a/tket-py/test/test_pass.py +++ b/tket-py/test/test_pass.py @@ -8,7 +8,6 @@ chunks, NormalizeGuppy, normalize_guppy, - # Gridsynth ) from tket.circuit import Tk2Circuit @@ -20,8 +19,6 @@ from tket.passes import PytketHugrPass from pytket.passes import CliffordSimp, SquashRzPhasedX, SequencePass from hugr.build.base import Hugr -# from selene_sim import build, Quest -# from hugr.qsystem.result import QsysResult import pytest @@ -219,19 +216,3 @@ def test_normalize_guppy(): c2 = Tk2Circuit(pytket_circ) normal_circ2 = normalize_guppy(c2) assert normal_circ2.circuit_cost(lambda op: int(op == TketOp.CX)) == 3 - - -# def test_gridsynth_pass(): -# alpha = 0.71 -# beta = 1.89 -# inverse_angle = - alpha - beta -# epsilon = 1e-2 - -# pytket_circ = Circuit(1).H(0).Rz(alpha, 0).Rz(beta, 0).Rz(inverse_angle, 0).H(0) -# circ = Tk2Circuit(pytket_circ) -# hugr = Hugr.from_str(circ.to_str()) -# gridsynth = Gridsynth(epsilon) -# gridsynth.run(hugr) -# runner = build(hugr, "test") -# shots = QsysResult( -# runner.run_shots(Quest(), n_qubits=1, n_shots=1)) From 11c517aeb14d871ef10a4578938bd585cf99ac1d Mon Sep 17 00:00:00 2001 From: Pablo Andres-Martinez <104848389+PabloAndresCQ@users.noreply.github.com> Date: Tue, 13 Jan 2026 10:45:51 +0000 Subject: [PATCH 46/48] Apply suggestions to inline comments from code review --- tket/src/passes/gridsynth.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index dbaf192f2..99ff45e2e 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -51,7 +51,7 @@ impl GarbageCollector { /// Remove reference to a constant node fn remove_references(&mut self, node: Node, increment: usize) { - // reduce reference count by 1 + // reduce reference count let count = self.references.get_mut(&node.index()).unwrap(); *count -= increment; } @@ -91,7 +91,6 @@ fn find_rzs(hugr: &mut Hugr) -> Option> { let op_type = hugr.get_optype(node); if op_matches(op_type, TketOp::Rz) { rz_nodes.push(node); - // return Some(node); } } @@ -99,11 +98,10 @@ fn find_rzs(hugr: &mut Hugr) -> Option> { if !(rz_nodes.is_empty()) { return Some(rz_nodes); } - // else return None None } -/// Find the output port and node linked to the input specified by `port_idz` for `node` +/// Find the output port and node linked to the input specified by `port_idx` for `node` fn find_single_linked_output_by_index( hugr: &mut Hugr, node: Node, @@ -252,7 +250,7 @@ fn replace_rz_with_gridsynth_output( let output_port = outputs[0]; let (next_node, dst_port) = hugr.single_linked_input(rz_node, output_port).unwrap(); - // we have now inferred what we need to know from the Rz node we are replacing and can remove it ao + // we have now inferred what we need to know from the Rz node we are replacing and can remove it hugr.remove_node(rz_node); // recursively adding next gate in gates to prev_node From e3d460910bf47933cc1e1167c2c90d18cce992aa Mon Sep 17 00:00:00 2001 From: Pablo Andres-Martinez <104848389+PabloAndresCQ@users.noreply.github.com> Date: Mon, 12 Jan 2026 14:47:34 +0100 Subject: [PATCH 47/48] fix: boost 1.90 dependecy conflict (#1353) Bumped tket-c-api dependency to avoid boost 1.90 dependency mismatch --- tket1-passes/conanfile.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tket1-passes/conanfile.txt b/tket1-passes/conanfile.txt index d235d38fd..01871ccce 100644 --- a/tket1-passes/conanfile.txt +++ b/tket1-passes/conanfile.txt @@ -1,2 +1,2 @@ [requires] -tket-c-api/2.1.64@tket/stable +tket-c-api/2.1.67@tket/stable From ce8dd55f49e96ad10dadf0f33f5c8595c07cb913 Mon Sep 17 00:00:00 2001 From: Pablo Andres-Martinez <104848389+PabloAndresCQ@users.noreply.github.com> Date: Thu, 29 Jan 2026 18:55:15 +0000 Subject: [PATCH 48/48] Gridsynth nit-picks and gate sequence normalisation (#1376) Merging into the open draft PR #1346 with some improvements --- tket-py/src/passes/gridsynth.rs | 8 +- tket-py/tket/_tket/passes.pyi | 5 +- tket-py/tket/passes.py | 12 +- tket/src/passes/gridsynth.rs | 214 ++++++++++++++++---------------- 4 files changed, 126 insertions(+), 113 deletions(-) diff --git a/tket-py/src/passes/gridsynth.rs b/tket-py/src/passes/gridsynth.rs index 386635989..d1de5bac0 100644 --- a/tket-py/src/passes/gridsynth.rs +++ b/tket-py/src/passes/gridsynth.rs @@ -16,11 +16,15 @@ create_py_exception!( /// Binding to a python function called gridsynth that runs the rust function called /// apply_gridsynth pass behind the scenes #[pyfunction] -pub fn gridsynth<'py>(circ: &Bound<'py, PyAny>, epsilon: f64) -> PyResult> { +pub fn gridsynth<'py>( + circ: &Bound<'py, PyAny>, + epsilon: f64, + simplify: bool, +) -> PyResult> { let py = circ.py(); try_with_circ(circ, |mut circ: tket::Circuit, typ: CircuitType| { - apply_gridsynth_pass(circ.hugr_mut(), epsilon).convert_pyerrs()?; + apply_gridsynth_pass(circ.hugr_mut(), epsilon, simplify).convert_pyerrs()?; let circ = typ.convert(py, circ)?; PyResult::Ok(circ) diff --git a/tket-py/tket/_tket/passes.pyi b/tket-py/tket/_tket/passes.pyi index b5b4e85c4..448685ba9 100644 --- a/tket-py/tket/_tket/passes.pyi +++ b/tket-py/tket/_tket/passes.pyi @@ -106,11 +106,14 @@ def tket1_pass( nested inside other subregions of the circuit. """ -def gridsynth(hugr: CircuitClass, epsilon: float) -> CircuitClass: +def gridsynth(hugr: CircuitClass, epsilon: float, simplify: bool) -> CircuitClass: """Runs a pass applying the gridsynth algorithm to all Rz gates in a HUGR, which decomposes them into the Clifford + T basis. Parameters: - hugr: the hugr to run the pass on. - epsilon: the precision of the gridsynth decomposition + - simplify: if `True`, each sequence of gridsynth gates is compressed into + a sequence of H*T and H*Tdg gates, sandwiched by Clifford gates. This sequence + always has a smaller number of S and H gates, and the same number of T+Tdg gates. """ diff --git a/tket-py/tket/passes.py b/tket-py/tket/passes.py index 4c239adad..2df63343c 100644 --- a/tket-py/tket/passes.py +++ b/tket-py/tket/passes.py @@ -182,6 +182,7 @@ def _normalize(self, hugr: Hugr, inplace: bool) -> PassResult: @dataclass class Gridsynth(ComposablePass): epsilon: float + simplify: bool = True """Apply the gridsynth algorithm to all Rz gates in the Hugr. @@ -191,6 +192,9 @@ class Gridsynth(ComposablePass): Parameters: - epsilon: The allowable error tolerance. + - simplify: If `True`, each sequence of gridsynth gates is compressed into + a sequence of H*T and H*Tdg gates, sandwiched by Clifford gates. This sequence + always has a smaller number of S and H gates, and the same number of T+Tdg gates. """ # TO DO: make the NormalizeGuppy pass optional, in case it is already run @@ -206,13 +210,15 @@ def run(self, hugr: Hugr, *, inplace: bool = True) -> PassResult: self, hugr=hugr, inplace=inplace, - copy_call=lambda h: self._apply_gridsynth_pass(hugr, self.epsilon, inplace), + copy_call=lambda h: self._apply_gridsynth_pass( + hugr, self.epsilon, self.simplify, inplace + ), ) def _apply_gridsynth_pass( - self, hugr: Hugr, epsilon: float, inplace: bool + self, hugr: Hugr, epsilon: float, simplify: bool, inplace: bool ) -> PassResult: compiler_state: Tk2Circuit = Tk2Circuit.from_bytes(hugr.to_bytes()) - program = gridsynth(compiler_state, epsilon) + program = gridsynth(compiler_state, epsilon, simplify) new_hugr = Hugr.from_str(program.to_str()) return PassResult.for_pass(self, hugr=new_hugr, inplace=inplace, result=None) diff --git a/tket/src/passes/gridsynth.rs b/tket/src/passes/gridsynth.rs index 99ff45e2e..0e26d7a7c 100644 --- a/tket/src/passes/gridsynth.rs +++ b/tket/src/passes/gridsynth.rs @@ -1,5 +1,12 @@ //! A pass that applies the gridsynth algorithm to all Rz gates in a HUGR. - +/// The pass introduced here assumes that (1) all functions have been inlined and +/// (2) that NormalizeGuppy has been run. It expects that the following is guaranteed: +/// * That every Const node is immediately connected to a LoadConst node. +/// * That every constant is used in a single place (i.e. that there's a single output +/// of each LoadConst). +/// * That we can find the Const node connected to an Rz node by first following the +/// input port 1 of the Rz node (i.e. the angle argument) and then iteratively +/// following the input on port 0 until we reach a Const node. use std::collections::HashMap; use crate::TketOp; @@ -131,8 +138,6 @@ fn find_angle_node( // As all of the NormalizeGuppy passes have been run on the `hugr` before it enters this function, // and these passes include constant folding, we can assume that we can follow the 0th ports back // to a constant node where the angle is defined. - let max_iterations = 10; - let mut ii = 0; let mut path = Vec::new(); // The nodes leading up to the angle_node and the angle_node // itself loop { @@ -156,12 +161,8 @@ fn find_angle_node( .or_insert(path); return angle_node; } - if ii >= max_iterations { - panic!("Angle finding failed"); - } prev_node = current_node; - ii += 1; } } @@ -188,10 +189,15 @@ fn find_angle(hugr: &mut Hugr, rz_node: Node, garbage_collector: &mut GarbageCol angle } -fn apply_gridsynth( +/// Call gridsynth on the angle of the Rz gate node provided. +/// If `simplify` is `true`, the sequence of gridsynth gates is compressed into +/// a sequence of H*T and H*Tdg gates, sandwiched by Clifford gates. This sequence +/// always has a smaller number of S and H gates, and the same number of T+Tdg gates. +fn get_gridsynth_gates( hugr: &mut Hugr, - epsilon: f64, rz_node: Node, + epsilon: f64, + simplify: bool, garbage_collector: &mut GarbageCollector, ) -> String { let theta = find_angle(hugr, rz_node, garbage_collector); @@ -200,113 +206,107 @@ fn apply_gridsynth( let up_to_phase = false; let mut gridsynth_config = config_from_theta_epsilon(theta, epsilon, seed, verbose, up_to_phase); - let gates = gridsynth_gates(&mut gridsynth_config); - gates.gates + let mut gate_sequence = gridsynth_gates(&mut gridsynth_config).gates; + + if simplify { + let n = gate_sequence.len(); + let mut normal_form_reached = false; + while !normal_form_reached { + // Not the most efficient, but it's easiest to reach the normal form by doing + // string rewrites. + // TODO: Can be done with Regex, preferably by providing all LHS to the Regex + // so they are all matched at once; then we replace each one accordingly. + // NOTE: Ignoring global phase factors + let new_gate_sequence = gate_sequence + // Cancellation rules + .replacen("ZZ", "", n) + .replacen("XX", "", n) + .replacen("HH", "", n) + .replacen("SS", "Z", n) + .replacen("TT", "S", n) + .replacen("DD", "SZ", n) + .replacen("TD", "", n) + .replacen("DT", "", n) + // Rules to push Paulis to the right + .replacen("ZS", "SZ", n) + .replacen("ZT", "TZ", n) + .replacen("ZD", "DZ", n) + .replacen("XS", "SZX", n) + .replacen("XT", "DX", n) + .replacen("XD", "TX", n) + .replacen("ZH", "HX", n) + .replacen("XH", "HZ", n) + .replacen("XZ", "ZX", n) + // Interaction of H and S (reduces number of H) + .replacen("HSH", "SHSX", n) + // Interaction of S and T (reduces number of S) + .replacen("DS", "T", n) + .replacen("SD", "T", n) + .replacen("TS", "DZ", n) + .replacen("ST", "DZ", n); + // Stop when no more changes are possible + normal_form_reached = new_gate_sequence == gate_sequence; + gate_sequence = new_gate_sequence; + } + } + gate_sequence } -/// Add a gridsynth gate to some previous node, which may or may not be a gridsynth gate, -/// and connect -fn add_gate_and_connect( - hugr: &mut Hugr, - prev_node: Node, - op: hugr::ops::OpType, - output_node: Node, - qubit_providing_node: Node, // The node providing qubit to Rz gate - qubit_providing_port: OutgoingPort, // The output port providing qubit to Rz gate -) -> Node { - let current_node = hugr.add_node_after(output_node, op); - let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); - - // If the previous node was the qubit_providing_node then it could have multiple - // outputs (eg, if multi-qubit gate and so need to be explicit about port) - let src_port = if prev_node.index() == qubit_providing_node.index() { - qubit_providing_port - } else { - // the ops generated by gridsynth are all single input single output gates, so - // it is safe to assume that there is only one output port - ports[0] - }; - let ports: Vec<_> = hugr.node_inputs(current_node).collect(); - let dst_port = ports[0]; - hugr.connect(prev_node, src_port, current_node, dst_port); - - current_node -} // TO DO: reduce number of arguments to this function. Six is too many. - fn replace_rz_with_gridsynth_output( hugr: &mut Hugr, rz_node: Node, gates: &str, ) -> Result<(), GridsynthError> { - // getting node and output port that gave qubit to Rz gate - let inputs: Vec<_> = hugr.node_inputs(rz_node).collect(); - let input_port = inputs[0]; - let (qubit_providing_node, qubit_providing_port) = - hugr.single_linked_output(rz_node, input_port).unwrap(); - let mut prev_node = qubit_providing_node; - - // find output port - let outputs: Vec<_> = hugr.node_outputs(rz_node).collect(); - let output_port = outputs[0]; - let (next_node, dst_port) = hugr.single_linked_input(rz_node, output_port).unwrap(); - - // we have now inferred what we need to know from the Rz node we are replacing and can remove it + // Remove the W i.e. the exp(i*pi/4) global phases + let gate_sequence = gates.replacen("W", "", gates.len()); + // Add the nodes of the gridsynth sequence into the HUGR + let gridsynth_nodes: Vec = gate_sequence + .chars() + .map(|gate| match gate { + 'H' => TketOp::H, + 'S' => TketOp::S, + 'T' => TketOp::T, + 'D' => TketOp::Tdg, + 'X' => TketOp::X, + 'Z' => TketOp::Z, + _ => panic!("The gate {gate} is not supported"), + }) + .map(|op| hugr.add_node_after(rz_node, op)) // No connections just yet + .collect(); // Force the nodes to actually be added + + // Get the node that connects to the input of the Rz gate + let rz_input_port = hugr.node_inputs(rz_node).next().unwrap(); + let (mut prev_node, mut prev_port) = hugr.single_linked_output(rz_node, rz_input_port).unwrap(); + // Get the node that connects to the output of the Rz gate + let rz_output_port = hugr.node_outputs(rz_node).next().unwrap(); + let (next_node, next_port) = hugr.single_linked_input(rz_node, rz_output_port).unwrap(); + // We have now inferred what we need to know from the Rz node; we can remove it hugr.remove_node(rz_node); - // recursively adding next gate in gates to prev_node - for gate in gates.chars() { - if gate == 'H' { - prev_node = add_gate_and_connect( - hugr, - prev_node, - TketOp::H.into(), - next_node, - qubit_providing_node, - qubit_providing_port, - ); - } else if gate == 'S' { - prev_node = add_gate_and_connect( - hugr, - prev_node, - TketOp::S.into(), - next_node, - qubit_providing_node, - qubit_providing_port, - ); - } else if gate == 'T' { - prev_node = add_gate_and_connect( - hugr, - prev_node, - TketOp::T.into(), - next_node, - qubit_providing_node, - qubit_providing_port, - ); - } else if gate == 'X' { - prev_node = add_gate_and_connect( - hugr, - prev_node, - TketOp::X.into(), - next_node, - qubit_providing_node, - qubit_providing_port, - ); - } else if gate == 'W' { - break; // Ignoring global phases for now. - } else { - panic!("The gate {gate} is not supported") - } + // Connect the gridsynth nodes + for current_node in gridsynth_nodes { + // Connect the current node with the previous node + let current_port = hugr.node_inputs(current_node).next().unwrap(); + hugr.connect(prev_node, prev_port, current_node, current_port); + // Update who is the prev_node + prev_node = current_node; + prev_port = hugr.node_outputs(prev_node).next().unwrap(); } - let ports: Vec<_> = hugr.node_outputs(prev_node).collect(); - // Assuming there were no outgoing ports to begin with when deciding port offset - let src_port = ports[0]; - hugr.connect(prev_node, src_port, next_node, dst_port); - hugr.validate()?; + // Finally, connect the last gridsynth node with the node that came after the Rz + hugr.connect(prev_node, prev_port, next_node, next_port); + // hugr.validate()?; Ok(()) } -/// Replace an Rz gate with the corresponding gates outputted by gridsynth -pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) -> Result<(), GridsynthError> { +/// Replace an Rz gate with the corresponding gates outputted by gridsynth. +/// If `simplify` is `true`, the sequence of gridsynth gates is compressed into +/// a sequence of H*T and H*Tdg gates, sandwiched by Clifford gates. This sequence +/// always has a smaller number of S and H gates, and the same number of T+Tdg gates. +pub fn apply_gridsynth_pass( + hugr: &mut Hugr, + epsilon: f64, + simplify: bool, +) -> Result<(), GridsynthError> { // Running passes to convert HUGR to standard form NormalizeGuppy::default() .simplify_cfgs(true) @@ -322,7 +322,7 @@ pub fn apply_gridsynth_pass(hugr: &mut Hugr, epsilon: f64) -> Result<(), Gridsyn path: HashMap::new(), }; for node in rz_nodes { - let gates = apply_gridsynth(hugr, epsilon, node, &mut garbage_collector); + let gates = get_gridsynth_gates(hugr, node, epsilon, simplify, &mut garbage_collector); replace_rz_with_gridsynth_output(hugr, node, &gates)?; } Ok(()) @@ -490,7 +490,7 @@ mod tests { // This test is just to check if a panic occurs let (mut circ, _) = build_rz_only_circ(); let epsilon: f64 = 1e-3; - apply_gridsynth_pass(&mut circ, epsilon).unwrap(); + apply_gridsynth_pass(&mut circ, epsilon, true).unwrap(); } #[test] @@ -502,7 +502,7 @@ mod tests { let epsilon = 1e-2; let mut hugr = build_non_trivial_circ(); - apply_gridsynth_pass(&mut hugr, epsilon).unwrap(); + apply_gridsynth_pass(&mut hugr, epsilon, true).unwrap(); } #[test] @@ -514,6 +514,6 @@ mod tests { let epsilon = 1e-2; let mut hugr = build_non_trivial_circ_2qubits(); - apply_gridsynth_pass(&mut hugr, epsilon).unwrap(); + apply_gridsynth_pass(&mut hugr, epsilon, true).unwrap(); } }