diff --git a/hpvm/tools/py-approxhpvm/main.py.in b/hpvm/tools/py-approxhpvm/main.py.in
index a472935f5f5f1a325ae8dc6ddc6782cdc5a64973..2f007a5317d53d45f4e89e852b57648748f7c9ab 100644
--- a/hpvm/tools/py-approxhpvm/main.py.in
+++ b/hpvm/tools/py-approxhpvm/main.py.in
@@ -20,10 +20,11 @@ HPVM_RT_PATH = "@HPVM_RT_PATH@"
 
 
 def compile_hpvm_c(
-    input_file: PathLike,
+    hpvm_src: PathLike,
     output_file: PathLike,
     tensor_target: Optional[str],
     opencl: bool,
+    link_bitcode: List[PathLike] = None,
     include: List[PathLike] = None,
     macro: List[str] = None,
     flags: List[str] = None,
@@ -55,19 +56,23 @@ def compile_hpvm_c(
     working_dir = Path(working_dir or ".")
     if not working_dir.is_dir():
         os.makedirs(working_dir)
-    name_stem = Path(input_file).stem
 
+    # All commands for compiling the main hpvm_c file
+    name_stem = Path(hpvm_src).stem
     ll_file = working_dir / f"{name_stem}.ll"
     hpvm_ll_file = working_dir / f"{name_stem}.hpvm.ll"
     llvm_ll_file = working_dir / f"{name_stem}.llvm.ll"
     hpvm_rt_linked_file = working_dir / f"{name_stem}.linked.bc"
     commands = [
-        hpvm_c_to_ll(input_file, ll_file, include, macro, flags, optim_level, std),
+        hpvm_c_to_ll(hpvm_src, ll_file, include, macro, flags, optim_level, std),
         opt_codegen_hpvm(ll_file, hpvm_ll_file),
         _run_opt(hpvm_ll_file, llvm_ll_file, passes, pass_flags),
         link_hpvm_rt(llvm_ll_file, hpvm_rt_linked_file),
-        link_binary(hpvm_rt_linked_file, output_file, link_dirs, link_libs),
     ]
+    link_bitcode_ = [Path(bc) for bc in (link_bitcode or [])]
+    commands.append(
+        link_binary(link_bitcode_ + [hpvm_rt_linked_file], output_file, link_dirs, link_libs)
+    )
     for command in commands:
         print(" ".join(command))
         check_output(command)
@@ -102,18 +107,19 @@ def link_hpvm_rt(src_file: PathLike, target_file: PathLike) -> List[str]:
 
 
 def link_binary(
-    src_file: PathLike,
+    src_files: List[PathLike],
     target_file: PathLike,
     extra_link_dirs: List[PathLike] = None,
     extra_link_libs: List[str] = None
 ) -> List[str]:
+    src_files_s = [str(file) for file in src_files]
     link_dirs, link_libs = _link_args(extra_link_dirs or [], extra_link_libs or [])
     linker_dir_flags = []
     for path in link_dirs:
         linker_dir_flags.extend([f"-L{path}", f"-Wl,-rpath={path}"])
     linker_lib_flags = [f"-l{lib}" for lib in link_libs]
     return [
-        str(LLVM_BUILD_BIN / "clang++"), str(src_file),
+        str(LLVM_BUILD_BIN / "clang++"), *src_files_s,
         "-o", str(target_file), *linker_dir_flags, *linker_lib_flags
     ]
 
@@ -155,8 +161,20 @@ def _run_opt(
 
 def parse_args():
     parser = argparse.ArgumentParser("approxhpvm")
-    parser.add_argument("input_file", type=Path, help="HPVM-C code to compile")
+    parser.add_argument(
+        "hpvm_src", type=Path,
+        help="""HPVM-C code to compile.
+HPVM-C code must be single file, but additional bitcode file can be linked together.
+See option -b for that."""
+    )
     parser.add_argument("output_file", type=Path, help="Path to generate binary to")
+    parser.add_argument(
+        "-b",
+        "--link-bitcode",
+        type=Path,
+        nargs="+",
+        help="Additional bitcode (.ll/.bc) files to link to",
+    )
     parser.add_argument(
         "-t",
         "--tensor-target",