diff --git a/hercules_opt/src/crc.rs b/hercules_opt/src/crc.rs
new file mode 100644
index 0000000000000000000000000000000000000000..be80e61bea8d6522a40b35542bb6b3c39edeb4db
--- /dev/null
+++ b/hercules_opt/src/crc.rs
@@ -0,0 +1,39 @@
+use hercules_ir::*;
+
+use crate::*;
+
+/*
+ * Top level function to collapse read chains in a function.
+ */
+pub fn crc(editor: &mut FunctionEditor) {
+    let mut changed = true;
+    while changed {
+        changed = false;
+        for id in editor.node_ids() {
+            if let Node::Read {
+                collect: lower_collect,
+                indices: ref lower_indices,
+            } = editor.func().nodes[id.idx()]
+                && let Node::Read {
+                    collect: upper_collect,
+                    indices: ref upper_indices,
+                } = editor.func().nodes[lower_collect.idx()]
+            {
+                let collapsed_read = Node::Read {
+                    collect: upper_collect,
+                    indices: upper_indices
+                        .iter()
+                        .chain(lower_indices.iter())
+                        .map(|idx| idx.clone())
+                        .collect(),
+                };
+                let success = editor.edit(|mut edit| {
+                    let new_id = edit.add_node(collapsed_read);
+                    let edit = edit.replace_all_uses(id, new_id)?;
+                    edit.delete_node(id)
+                });
+                changed = changed || success;
+            }
+        }
+    }
+}
diff --git a/hercules_opt/src/lib.rs b/hercules_opt/src/lib.rs
index 9935703e839b5a4dd705af03f40a456008fe0f12..e351deba58c9061fe19bba4932509177d83af626 100644
--- a/hercules_opt/src/lib.rs
+++ b/hercules_opt/src/lib.rs
@@ -1,6 +1,7 @@
 #![feature(let_chains)]
 
 pub mod ccp;
+pub mod crc;
 pub mod dce;
 pub mod delete_uncalled;
 pub mod editor;
@@ -23,6 +24,7 @@ pub mod unforkify;
 pub mod utils;
 
 pub use crate::ccp::*;
+pub use crate::crc::*;
 pub use crate::dce::*;
 pub use crate::delete_uncalled::*;
 pub use crate::editor::*;
diff --git a/hercules_opt/src/pass.rs b/hercules_opt/src/pass.rs
index 4f44d1d1a833b808a23ef3e56338097a1b874a02..e528b35de7a2e94fd94a8014008073c15548cbd7 100644
--- a/hercules_opt/src/pass.rs
+++ b/hercules_opt/src/pass.rs
@@ -25,6 +25,7 @@ pub enum Pass {
     PhiElim,
     Forkify,
     ForkGuardElim,
+    CRC,
     SLF,
     WritePredication,
     Predication,
@@ -471,6 +472,33 @@ impl PassManager {
                     }
                     self.clear_analyses();
                 }
+                Pass::CRC => {
+                    self.make_def_uses();
+                    let def_uses = self.def_uses.as_ref().unwrap();
+                    for idx in 0..self.module.functions.len() {
+                        let constants_ref =
+                            RefCell::new(std::mem::take(&mut self.module.constants));
+                        let dynamic_constants_ref =
+                            RefCell::new(std::mem::take(&mut self.module.dynamic_constants));
+                        let types_ref = RefCell::new(std::mem::take(&mut self.module.types));
+                        let mut editor = FunctionEditor::new(
+                            &mut self.module.functions[idx],
+                            FunctionID::new(idx),
+                            &constants_ref,
+                            &dynamic_constants_ref,
+                            &types_ref,
+                            &def_uses[idx],
+                        );
+                        crc(&mut editor);
+
+                        self.module.constants = constants_ref.take();
+                        self.module.dynamic_constants = dynamic_constants_ref.take();
+                        self.module.types = types_ref.take();
+
+                        self.module.functions[idx].delete_gravestones();
+                    }
+                    self.clear_analyses();
+                }
                 Pass::SLF => {
                     self.make_def_uses();
                     self.make_reverse_postorders();
@@ -498,7 +526,6 @@ impl PassManager {
                         self.module.dynamic_constants = dynamic_constants_ref.take();
                         self.module.types = types_ref.take();
 
-                        println!("{}", self.module.functions[idx].name);
                         self.module.functions[idx].delete_gravestones();
                     }
                     self.clear_analyses();
diff --git a/hercules_rt/src/lib.rs b/hercules_rt/src/lib.rs
index eeb09eb6859fef91c10f2026bbb8553274195cae..60d3470edc8cf42dd105cb4a2835a2a86d00fe3f 100644
--- a/hercules_rt/src/lib.rs
+++ b/hercules_rt/src/lib.rs
@@ -199,7 +199,6 @@ impl<'b, 'a: 'b> HerculesBox<'a> {
     }
 
     pub unsafe fn __zeros(size: u64) -> Self {
-        assert_ne!(size, 0);
         let size = size as usize;
         let id = NUM_OBJECTS.fetch_add(1, Ordering::Relaxed);
         HerculesBox {
diff --git a/juno_frontend/src/lib.rs b/juno_frontend/src/lib.rs
index 8ca9d6792633e3e5bc4ea551763fe3f8bb8401cd..c06ebf34e293afc10ff84e45fa422c3c2dabad5d 100644
--- a/juno_frontend/src/lib.rs
+++ b/juno_frontend/src/lib.rs
@@ -182,6 +182,8 @@ pub fn compile_ir(
     add_pass!(pm, verify, WritePredication);
     add_pass!(pm, verify, PhiElim);
     add_pass!(pm, verify, DCE);
+    add_pass!(pm, verify, CRC);
+    add_pass!(pm, verify, DCE);
     add_pass!(pm, verify, SLF);
     add_pass!(pm, verify, DCE);
     add_pass!(pm, verify, Predication);