diff --git a/hercules_opt/src/ccp.rs b/hercules_opt/src/ccp.rs
index cf3a0919585b4254ff4d3f6996755c063bca68d6..b8eb57ca513197bcd638f48106bed4d14a364539 100644
--- a/hercules_opt/src/ccp.rs
+++ b/hercules_opt/src/ccp.rs
@@ -383,8 +383,14 @@ fn ccp_flow_function(
         }),
         // If node has only one output, if doesn't directly handle crossover of
         // reachability and constant propagation. Read handles that.
-        Node::If { control, cond: _ } => inputs[control.idx()].clone(),
-        Node::Match { control, sum: _ } => inputs[control.idx()].clone(),
+        Node::If { control, cond } => {
+            assert!(!inputs[control.idx()].is_reachable() || inputs[cond.idx()].is_reachable());
+            inputs[control.idx()].clone()
+        }
+        Node::Match { control, sum } => {
+            assert!(!inputs[control.idx()].is_reachable() || inputs[sum.idx()].is_reachable());
+            inputs[control.idx()].clone()
+        }
         Node::Fork {
             control,
             factors: _,
@@ -426,9 +432,21 @@ fn ccp_flow_function(
         // TODO: At least for now, reduce nodes always produce unknown values.
         Node::Reduce {
             control,
-            init: _,
-            reduct: _,
-        } => inputs[control.idx()].clone(),
+            init,
+            reduct,
+        } => {
+            let reachability = inputs[control.idx()].reachability.clone();
+            if reachability == ReachabilityLattice::Reachable {
+                assert!(inputs[init.idx()].is_reachable());
+                let mut constant = inputs[init.idx()].constant.clone();
+                if inputs[reduct.idx()].is_reachable() {
+                    constant = ConstantLattice::meet(&constant, &inputs[reduct.idx()].constant);
+                }
+                CCPLattice { reachability, constant }
+            } else {
+                CCPLattice { reachability, constant: ConstantLattice::top() }
+            }
+        },
         Node::Return { control, data } => inputs[control.idx()].clone(),
         Node::Parameter { index: _ } => CCPLattice::bottom(),
         // A constant node is the "source" of concrete constant lattice values.