diff --git a/Cargo.lock b/Cargo.lock
index 37216ee3fbaf095900ca648fcbcad447ef3af34c..1f9d1747a6ee3734825aeb18d792164cf6f99f19 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -712,6 +712,16 @@ dependencies = [
  "with_builtin_macros",
 ]
 
+[[package]]
+name = "juno_casts_and_intrinsics"
+version = "0.1.0"
+dependencies = [
+ "async-std",
+ "hercules_rt",
+ "juno_build",
+ "with_builtin_macros",
+]
+
 [[package]]
 name = "juno_frontend"
 version = "0.1.0"
diff --git a/Cargo.toml b/Cargo.toml
index c6b2468fb9d41b467d48221d6621d9fcbb197034..a34845f8b26aeb97d076e7ebfcf8125efa43473c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,6 +20,7 @@ members = [
 	"juno_scheduler",
 	"juno_build",
 
-	"juno_samples/matmul",
 	"juno_samples/simple3",
+	"juno_samples/matmul",
+	"juno_samples/casts_and_intrinsics",
 ]
diff --git a/hercules_cg/src/cpu.rs b/hercules_cg/src/cpu.rs
index eaa7374b7a8f6c3df66a9a5085d179a143b81d34..8437e9e44b2c7792b54f563f86f59ee5fa6bd23a 100644
--- a/hercules_cg/src/cpu.rs
+++ b/hercules_cg/src/cpu.rs
@@ -597,7 +597,54 @@ impl<'a> CPUContext<'a> {
                             write!(w, ", -1")?;
                         }
                     }
-                    SUnaryOperator::Cast(_) => todo!(),
+                    SUnaryOperator::Cast(dst_ty) => {
+                        let src_ty = &self.svalue_types[input];
+                        if src_ty.is_integer()
+                            && dst_ty.is_integer()
+                            && src_ty.num_bits() > dst_ty.num_bits()
+                        {
+                            write!(w, "trunc ")?;
+                        } else if src_ty.is_signed()
+                            && dst_ty.is_integer()
+                            && src_ty.num_bits() < dst_ty.num_bits()
+                        {
+                            write!(w, "sext ")?;
+                        } else if src_ty.is_integer()
+                            && dst_ty.is_integer()
+                            && src_ty.num_bits() < dst_ty.num_bits()
+                        {
+                            write!(w, "zext ")?;
+                        } else if src_ty.is_integer() && dst_ty.is_integer() {
+                            // A no-op.
+                            write!(w, "bitcast ")?;
+                        } else if src_ty.is_float()
+                            && dst_ty.is_float()
+                            && src_ty.num_bits() > dst_ty.num_bits()
+                        {
+                            write!(w, "fptrunc ")?;
+                        } else if src_ty.is_float()
+                            && dst_ty.is_float()
+                            && src_ty.num_bits() < dst_ty.num_bits()
+                        {
+                            write!(w, "fpext ")?;
+                        } else if src_ty.is_float() && dst_ty.is_float() {
+                            // A no-op.
+                            write!(w, "bitcast ")?;
+                        } else if src_ty.is_float() && dst_ty.is_signed() {
+                            write!(w, "fptosi ")?;
+                        } else if src_ty.is_float() && dst_ty.is_integer() {
+                            write!(w, "fptoui ")?;
+                        } else if src_ty.is_signed() && dst_ty.is_float() {
+                            write!(w, "sitofp ")?;
+                        } else if src_ty.is_integer() && dst_ty.is_float() {
+                            write!(w, "uitofp ")?;
+                        } else {
+                            panic!("PANIC: Invalid cast type combination.");
+                        }
+                        self.emit_svalue(input, true, w)?;
+                        write!(w, " to ")?;
+                        self.emit_type(dst_ty, w)?;
+                    }
                 }
             }
             SInst::Binary { left, right, op } => {
@@ -677,6 +724,24 @@ impl<'a> CPUContext<'a> {
                     }
                 }
             }
+            SInst::IntrinsicCall { intrinsic, args } => {
+                emit_assign(w)?;
+                write!(w, "call ")?;
+                self.emit_type(&self.svalue_types[&self_svalue], w)?;
+                write!(
+                    w,
+                    " @llvm.{}.{}(",
+                    // TODO: make lower case names conform to LLVM expectations.
+                    intrinsic.lower_case_name(),
+                    Self::intrinsic_type_str(&self.svalue_types[&self_svalue])
+                )?;
+                self.emit_svalue(&args[0], true, w)?;
+                for idx in 1..args.len() {
+                    write!(w, ", ")?;
+                    self.emit_svalue(&args[idx], true, w)?;
+                }
+                write!(w, ")")?;
+            }
             SInst::ProductExtract { product, indices } => {
                 emit_assign(w)?;
                 write!(w, "extractvalue ")?;
diff --git a/hercules_cg/src/sched_gen.rs b/hercules_cg/src/sched_gen.rs
index e5378b9cca4ae553ff8a760202db0526b13f7211..70a898b6c259b8bf7543b5ff4d1202132c71cf9b 100644
--- a/hercules_cg/src/sched_gen.rs
+++ b/hercules_cg/src/sched_gen.rs
@@ -1071,6 +1071,17 @@ impl<'a> FunctionContext<'a> {
                     self.stypes[self.typing[id.idx()].idx()].clone().unwrap(),
                 ));
             }
+            Node::IntrinsicCall {
+                intrinsic,
+                ref args,
+            } => {
+                let args = args.iter().map(|id| get_svalue(*id).clone()).collect();
+                block.insts.push(SInst::IntrinsicCall { intrinsic, args });
+                block.virt_regs.push((
+                    self_virt_reg(),
+                    self.stypes[self.typing[id.idx()].idx()].clone().unwrap(),
+                ));
+            }
 
             Node::Read {
                 collect,
diff --git a/hercules_cg/src/sched_ir.rs b/hercules_cg/src/sched_ir.rs
index 3ceee621f4469127c40453e364b87a230a947e85..6a482443eaf39c6f3b87c7b19ec06adbe67ff5ad 100644
--- a/hercules_cg/src/sched_ir.rs
+++ b/hercules_cg/src/sched_ir.rs
@@ -213,6 +213,28 @@ impl SType {
         }
     }
 
+    pub fn is_signed(&self) -> bool {
+        match self {
+            SType::Integer8 | SType::Integer16 | SType::Integer32 | SType::Integer64 => true,
+            _ => false,
+        }
+    }
+
+    pub fn is_integer(&self) -> bool {
+        self.is_unsigned() || self.is_signed() || *self == SType::Boolean
+    }
+
+    pub fn num_bits(&self) -> u8 {
+        match self {
+            SType::Boolean => 1,
+            SType::Integer8 | SType::UnsignedInteger8 => 8,
+            SType::Integer16 | SType::UnsignedInteger16 => 16,
+            SType::Integer32 | SType::UnsignedInteger32 | SType::Float32 => 32,
+            SType::Integer64 | SType::UnsignedInteger64 | SType::Float64 => 64,
+            _ => panic!(),
+        }
+    }
+
     pub fn try_product(&self) -> Option<&[SType]> {
         if let SType::Product(fields) = self {
             Some(fields)
@@ -334,6 +356,10 @@ pub enum SInst {
         third: SValue,
         op: STernaryOperator,
     },
+    IntrinsicCall {
+        intrinsic: Intrinsic,
+        args: Box<[SValue]>,
+    },
     ProductExtract {
         product: SValue,
         indices: Box<[usize]>,
@@ -487,6 +513,7 @@ impl SInst {
                 third: _,
                 op,
             } => op.upper_case_name(),
+            SInst::IntrinsicCall { intrinsic, args: _ } => intrinsic.upper_case_name(),
             SInst::ProductExtract {
                 product: _,
                 indices: _,
diff --git a/hercules_cg/src/sched_schedule.rs b/hercules_cg/src/sched_schedule.rs
index 16720bbc60380866cd2dbd868ebf9f6cbd5a91fe..4ba407f0e316e6611e311ff095bff6121a922c5a 100644
--- a/hercules_cg/src/sched_schedule.rs
+++ b/hercules_cg/src/sched_schedule.rs
@@ -44,7 +44,7 @@ pub fn sched_get_uses(inst: &SInst) -> Box<dyn Iterator<Item = &SValue> + '_> {
             false_target: _,
             true_target: _,
         } => Box::new(once(cond)),
-        SInst::PartitionExit { data_outputs } => Box::new(data_outputs.iter().map(|svalue| svalue)),
+        SInst::PartitionExit { data_outputs } => Box::new(data_outputs.iter()),
         SInst::Return { value } => Box::new(once(value)),
         SInst::Unary { input, op: _ } => Box::new(once(input)),
         SInst::Binary { left, right, op: _ } => Box::new(once(left).chain(once(right))),
@@ -54,6 +54,7 @@ pub fn sched_get_uses(inst: &SInst) -> Box<dyn Iterator<Item = &SValue> + '_> {
             third,
             op: _,
         } => Box::new(once(first).chain(once(second)).chain(once(third))),
+        SInst::IntrinsicCall { intrinsic: _, args } => Box::new(args.iter()),
         SInst::ProductExtract {
             product,
             indices: _,
diff --git a/hercules_ir/src/gcm.rs b/hercules_ir/src/gcm.rs
index 3180a88b215dfcc36817abef816795561e03f4da..19df2d6bb3a42c4c989e9d04eb84b37caa6cf4a0 100644
--- a/hercules_ir/src/gcm.rs
+++ b/hercules_ir/src/gcm.rs
@@ -18,7 +18,6 @@ pub fn gcm(
     antideps: &Vec<(NodeID, NodeID)>,
     loops: &LoopTree,
     fork_join_map: &HashMap<NodeID, NodeID>,
-    partial_partition: &mut Vec<Option<PartitionID>>,
 ) -> Vec<NodeID> {
     let mut bbs: Vec<Option<NodeID>> = vec![None; function.nodes.len()];
 
@@ -186,30 +185,12 @@ pub fn gcm(
         // #[feature(iter_collect_into)]
 
         // Look between the LCA and the schedule early location to place the
-        // node. If a data node can't be scheduled to any control nodes in its
-        // partition (this may happen if all of the control nodes in a partition
-        // got deleted, for example), then the data node can be scheduled into a
-        // control node in a different partition.
+        // node.
         let schedule_early = schedule_early[id.idx()].unwrap();
-        let need_to_repartition = !dom
-            .chain(lca.unwrap_or(schedule_early), schedule_early)
-            .any(|dominator| {
-                partial_partition[id.idx()].is_none()
-                    || partial_partition[dominator.idx()] == partial_partition[id.idx()]
-            });
-        if need_to_repartition {
-            partial_partition[id.idx()] = None;
-        }
         let mut chain = dom
             // If the node has no users, then it doesn't really matter where we
             // place it - just place it at the early placement.
-            .chain(lca.unwrap_or(schedule_early), schedule_early)
-            // Filter the dominator chain by control nodes in the same partition
-            // as this data node, if the data node is in a partition already.
-            .filter(|dominator| {
-                partial_partition[id.idx()].is_none()
-                    || partial_partition[dominator.idx()] == partial_partition[id.idx()]
-            });
+            .chain(lca.unwrap_or(schedule_early), schedule_early);
         let mut location = chain.next().unwrap();
         while let Some(control_node) = chain.next() {
             // If the next node further up the dominator tree is in a shallower
diff --git a/hercules_opt/src/editor.rs b/hercules_opt/src/editor.rs
index 3286fa884663450ab0b15915467e1e82cfc428ff..a75ea38aa3b7703e7efecc952b54d9ccb8df45c6 100644
--- a/hercules_opt/src/editor.rs
+++ b/hercules_opt/src/editor.rs
@@ -687,16 +687,9 @@ pub fn repair_plan(plan: &mut Plan, new_function: &Function, edits: &[Edit]) {
         &antideps,
         &loops,
         &fork_join_map,
-        &mut new_partitions,
     );
-    let added_and_to_repartition_data_nodes: Vec<NodeID> = new_partitions
-        .iter()
-        .enumerate()
-        .filter(|(_, part)| part.is_none())
-        .map(|(idx, _)| NodeID::new(idx))
-        .collect();
-    for data_id in added_and_to_repartition_data_nodes {
-        new_partitions[data_id.idx()] = new_partitions[bbs[data_id.idx()].idx()];
+    for data_idx in 0..new_function.nodes.len() {
+        new_partitions[data_idx] = new_partitions[bbs[data_idx].idx()];
     }
 
     // Step 6: create a solitary gravestone partition. This will get removed
diff --git a/hercules_opt/src/pass.rs b/hercules_opt/src/pass.rs
index 03aff10ade7e4aca8ecf58d94127a405640eb7e3..f5e0a9ad5ac9a081efe3016cd0dcb6430c688bc6 100644
--- a/hercules_opt/src/pass.rs
+++ b/hercules_opt/src/pass.rs
@@ -275,7 +275,6 @@ impl PassManager {
                             antideps,
                             loops,
                             fork_join_map,
-                            &mut vec![None; function.nodes.len()],
                         )
                     },
                 )
diff --git a/juno_samples/casts_and_intrinsics/Cargo.toml b/juno_samples/casts_and_intrinsics/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..f49797969012f5195a0338b7b14fa04414dddb03
--- /dev/null
+++ b/juno_samples/casts_and_intrinsics/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "juno_casts_and_intrinsics"
+version = "0.1.0"
+authors = ["Russel Arbore <rarbore2@illinois.edu>"]
+edition = "2021"
+
+[[bin]]
+name = "juno_casts_and_intrinsics"
+path = "src/main.rs"
+
+[build-dependencies]
+juno_build = { path = "../../juno_build" }
+
+[dependencies]
+juno_build = { path = "../../juno_build" }
+hercules_rt = { path = "../../hercules_rt" }
+with_builtin_macros = "0.1.0"
+async-std = "*"
diff --git a/juno_samples/casts_and_intrinsics/build.rs b/juno_samples/casts_and_intrinsics/build.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8422f7e60619b48aca2d5e783eaed45e70be71c3
--- /dev/null
+++ b/juno_samples/casts_and_intrinsics/build.rs
@@ -0,0 +1,12 @@
+extern crate juno_build;
+use juno_build::JunoCompiler;
+
+fn main() {
+    JunoCompiler::new()
+        .file_in_src("casts_and_intrinsics.jn")
+        .unwrap()
+        .schedule_in_src("casts_and_intrinsics.sch")
+        .unwrap()
+        .build()
+        .unwrap();
+}
diff --git a/juno_samples/casts_and_intrinsics/src/casts_and_intrinsics.jn b/juno_samples/casts_and_intrinsics/src/casts_and_intrinsics.jn
new file mode 100644
index 0000000000000000000000000000000000000000..5261063353496496e3e994a91620073438528ccd
--- /dev/null
+++ b/juno_samples/casts_and_intrinsics/src/casts_and_intrinsics.jn
@@ -0,0 +1,5 @@
+#[entry]
+fn casts_and_intrinsics(input : f32) -> i32 {
+  let sqrt = sqrt!::<f32>(input);
+  return sqrt as i32;
+}
diff --git a/juno_samples/casts_and_intrinsics/src/casts_and_intrinsics.sch b/juno_samples/casts_and_intrinsics/src/casts_and_intrinsics.sch
new file mode 100644
index 0000000000000000000000000000000000000000..80ec2766eac8850ff736cd8a1f52dbe87bf24553
--- /dev/null
+++ b/juno_samples/casts_and_intrinsics/src/casts_and_intrinsics.sch
@@ -0,0 +1,2 @@
+function casts_and_intrinsics {
+}
diff --git a/juno_samples/casts_and_intrinsics/src/main.rs b/juno_samples/casts_and_intrinsics/src/main.rs
new file mode 100644
index 0000000000000000000000000000000000000000..344168e0e1995becff3b4580f4d957002a9ee2a5
--- /dev/null
+++ b/juno_samples/casts_and_intrinsics/src/main.rs
@@ -0,0 +1,22 @@
+#![feature(future_join)]
+
+extern crate async_std;
+extern crate juno_build;
+extern crate hercules_rt;
+
+juno_build::juno!("casts_and_intrinsics");
+
+fn main() {
+    async_std::task::block_on(async {
+        let output = unsafe {
+            casts_and_intrinsics(16.0).await
+        };
+        println!("{}", output);
+        assert_eq!(output, 4);
+    });
+}
+
+#[test]
+fn casts_and_intrinsics_test() {
+    main();
+}