diff --git a/hercules_opt/src/loop_bound_canon.rs b/hercules_opt/src/loop_bound_canon.rs
index 680236f168c04fb26f8f8befd9ea865835235fca..e305e9dbb4380a148493e21fcfe018f85553593c 100644
--- a/hercules_opt/src/loop_bound_canon.rs
+++ b/hercules_opt/src/loop_bound_canon.rs
@@ -47,6 +47,8 @@ pub fn canonicalize_single_loop_bounds(
 ) -> bool {
     let function = editor.func();
 
+    println!("canonicalizing {:?}", l.header);
+
     let Some(loop_condition) = get_loop_exit_conditions(function, l, control_subgraph) else {
         return false;
     };
@@ -65,7 +67,7 @@ pub fn canonicalize_single_loop_bounds(
 
     if has_canonical_iv(editor, l, &ivs).is_some() {
         // println!("has canon iv!");
-        return true;
+        return false;
     }
 
     let loop_bound_iv_phis = get_loop_condition_ivs(editor, l, &ivs, &loop_condition);
@@ -268,17 +270,20 @@ pub fn canonicalize_single_loop_bounds(
                 edit.replace_all_uses_where(bound_id, new_condition, |usee| *usee == binop_node)?;
         }
 
-        // Add back to uses of the IV
-        for user in update_expr_users {
-            let new_user = Node::Binary {
-                left: user,
-                right: *initializer,
-                op: BinaryOperator::Add,
-            };
-            let new_user = edit.add_node(new_user);
-            edit = edit.replace_all_uses(user, new_user)?;
-        }
 
+        // for user in update_expr_users {
+        //     let new_user = Node::Binary {
+        //         left: user,
+        //         right: *initializer,
+        //         op: BinaryOperator::Add,
+        //     };
+        //     let new_user = edit.add_node(new_user);
+        //     edit = edit.replace_all_uses(user, new_user)?;
+        // }
+
+        // for 
+
+        // Add the offset back to users of the IV update expression
         let new_user = Node::Binary {
             left: *update_expression,
             right: *initializer,
@@ -292,6 +297,7 @@ pub fn canonicalize_single_loop_bounds(
                 && *usee != condition_node
         })?;
 
+        // Add the offset back to users of the IV directly
         let new_user = Node::Binary {
             left: *iv_phi,
             right: *initializer,
@@ -305,5 +311,6 @@ pub fn canonicalize_single_loop_bounds(
         Ok(edit)
     });
 
+    println!("result: {:?}", result);
     return result;
 }
diff --git a/juno_samples/cava/src/cpu.sch b/juno_samples/cava/src/cpu.sch
index 1b595b052582740c0a4886041fa8de2d54cfc5b2..4013fd277051b425b116486be78a6555e920b2d7 100644
--- a/juno_samples/cava/src/cpu.sch
+++ b/juno_samples/cava/src/cpu.sch
@@ -38,6 +38,7 @@ fixpoint {
 }
 simpl!(fuse1);
 array-slf(fuse1);
+loop-bound-canon(fuse1);
 
 inline(fuse2);
 no-memset(fuse2@res);
diff --git a/juno_samples/fork_join_tests/src/cpu.sch b/juno_samples/fork_join_tests/src/cpu.sch
index 7c416e904ad5d43a5297496b6de40037f5b9b553..c71aec111f42aad90c383f8b42f622037efac60c 100644
--- a/juno_samples/fork_join_tests/src/cpu.sch
+++ b/juno_samples/fork_join_tests/src/cpu.sch
@@ -25,10 +25,14 @@ gvn(*);
 phi-elim(*);
 dce(*);
 
+lift-dc-math(*);
+loop-bound-canon(*);
+
 fixpoint panic after 20 {
   forkify(*);
   fork-guard-elim(*);
-  fork-coalesce(*);  
+  fork-coalesce(*);
+  dce(*);  
 }
 
 dce(*);
diff --git a/juno_samples/fork_join_tests/src/fork_join_tests.jn b/juno_samples/fork_join_tests/src/fork_join_tests.jn
index 8f569cfbe75105054e60c5d9bbb84b8ebbac6041..51115f1576edd1d555395717bdc1dcb4e82a2529 100644
--- a/juno_samples/fork_join_tests/src/fork_join_tests.jn
+++ b/juno_samples/fork_join_tests/src/fork_join_tests.jn
@@ -12,7 +12,7 @@ fn test1(input : i32) -> i32[4, 4] {
 #[entry]
 fn test2(input : i32) -> i32[4, 5] {
   let arr : i32[4, 5];
-  @loop1 for i = 0 to 8 {
+  @loop1 for i = 1 to 9 {
     @loop2 for k = 0 to 5 {
       @loop3 for j = 0 to 4 {
         arr[j, k] += input;
diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs
index d5c0af27e280d523683cec2b39da387a3f2c3f45..6931ce2e17680146f68da4ad4c61a50dffcaadb0 100644
--- a/juno_scheduler/src/pm.rs
+++ b/juno_scheduler/src/pm.rs
@@ -2771,29 +2771,35 @@ fn run_pass(
         }
         Pass::LoopBoundCanon => {
             assert_eq!(args.len(), 0);
+            loop {
+                let mut inner_changed = false;
+                pm.make_fork_join_maps();
+                pm.make_loops();
+                pm.make_control_subgraphs();
+                let fork_join_maps = pm.fork_join_maps.take().unwrap();
+                let loops = pm.loops.take().unwrap();
+                let control_subgraphs = pm.control_subgraphs.take().unwrap();
 
-            pm.make_fork_join_maps();
-            pm.make_loops();
-            pm.make_control_subgraphs();
-            let fork_join_maps = pm.fork_join_maps.take().unwrap();
-            let loops = pm.loops.take().unwrap();
-            let control_subgraphs = pm.control_subgraphs.take().unwrap();
-
-            for (((func, fork_join_map), loops), control_subgraph) in
-                build_selection(pm, selection, false)
-                    .into_iter()
-                    .zip(fork_join_maps.iter())
-                    .zip(loops.iter())
-                    .zip(control_subgraphs.iter())
-            {
-                let Some(mut func) = func else {
-                    continue;
-                };
-                loop_bound_canon_toplevel(&mut func, fork_join_map, control_subgraph, loops);
-                changed |= func.modified();
+                for (((func, fork_join_map), loops), control_subgraph) in
+                    build_selection(pm, selection.clone(), false)
+                        .into_iter()
+                        .zip(fork_join_maps.iter())
+                        .zip(loops.iter())
+                        .zip(control_subgraphs.iter())
+                {
+                    let Some(mut func) = func else {
+                        continue;
+                    };
+                    loop_bound_canon_toplevel(&mut func, fork_join_map, control_subgraph, loops);
+                    changed |= func.modified();
+                    inner_changed |= func.modified();
+                }
+                pm.delete_gravestones();
+                pm.clear_analyses();
+                if !inner_changed {
+                    break;
+                }
             }
-            pm.delete_gravestones();
-            pm.clear_analyses();
         }
     }
     println!("Ran Pass: {:?}", pass);