LLC(1)

πŸ’… llc β€” the LLVM static compiler, bestie edition

okay so real talk: llc is the LLVM static compiler and she is, like, the main character of getting your code from LLVM-land into actual assembly. no cap. πŸŽ€


✨ SYNOPSIS ✨

llc [options] [filename]

🌸 DESCRIPTION 🌸

so here's the vibe πŸ’– β€” llc takes your LLVM source inputs and compiles them into assembly language for whatever architecture you point it at. then you can take that assembly, run it through a native assembler and linker, and boom 🫢 you got yourself a native executable. iconic behavior honestly.

and like, which architecture does it pick? it automatically figures that out from your input file β€” unless you use the -march option to override the default. she's smart but she also listens to you, yk? ⭐


🌈 OPTIONS 🌈

so first, the file reading situation 🧚 β€” if filename is - or just... omitted entirely, llc reads from standard input. otherwise it reads from filename. and your inputs can be in either LLVM assembly language format (.ll) or LLVM bitcode format (.bc). both slay. πŸ’…

then, the output situation β€” if you omit the -o option, llc sends its output to standard output if the input is from standard input. and if -o specifies -, the output also goes to standard output. same energy. ✨

but if there's no -o option and your input file is something other than -, then llc invents the output filename for you: it takes the input filename, strips any existing .bc extension, and slaps on a .s suffix. she's so thoughtful 😭

the rest of the llc options are down below, let's gooo πŸ‘‘

πŸ¦‹ End-user Options πŸ¦‹

  • -help β€” prints a summary of all the command line options. your little map. πŸ—ΊοΈ
  • -M β€” passes through target-specific InstPrinter options. just go look at the -M option of llvm-objdump(1) <llvm-objdump.html> for the deets.
  • -o <filename> β€” uses <filename> as your output filename. see the summary up above for the whole story. πŸ’–
  • -O=uint β€” generates code at different optimization levels. these line up with the -O0, -O1, -O2, and -O3 optimization levels that clang uses. pick your fighter ✨
  • -mtriple=<target triple> β€” overrides the target triple that's specified in the input file with whatever string you hand her. 🎯
  • -march=<arch> β€” specifies the architecture to generate assembly for, overriding the target encoded in the input file. wanna see the valid architectures? run llc -help and look at the output. by default this gets inferred from the target triple, or autodetected to the current architecture. no manual labour required πŸ’…
  • -mcpu=<cpuname> β€” specifies a specific chip in the current architecture to generate code for. by default it's inferred from the target triple and autodetected to the current architecture. for a list of available CPUs, use:
llvm-as < /dev/null | llc -march=xyz -mcpu=help
  • -filetype=<output file type> β€” specifies what kind of output llc should generate. the options are: asm for textual assembly ('.s'), obj for native object files ('.o'), and null for not emitting anything at all (for performance testing β€” yes, the void, she contains multitudes πŸ’€).
heads up bestie: not all targets support all options. 🫢
  • -mattr=a1,+a2,-a3,... β€” override or control specific attributes of the target, like whether SIMD operations are enabled or not. the default set of attributes is set by the current CPU. for a list of available attributes, use:
llvm-as < /dev/null | llc -march=xyz -mattr=help
  • --frame-pointer β€” specifies the effect of the frame pointer elimination optimization. values are all, non-leaf, none. πŸŽ€
  • --disable-excess-fp-precision β€” disables optimizations that may produce excess precision for floating point.
⚠️ but like, seriously β€” this option can dramatically slow down code on some systems (e.g. X86). she's giving "worth it for correctness, tragic for speed" energy.
  • --enable-no-infs-fp-math β€” enables optimizations that assume there are no Inf values. πŸ™ˆ
  • --enable-no-nans-fp-math β€” enables optimizations that assume there are no NAN values. πŸ™ˆ
  • --enable-no-signed-zeros-fp-math β€” enables FP math optimizations that assume the sign of 0 is insignificant. (she said what she said about negative zero πŸ’…)
  • --enable-no-trapping-fp-math β€” enables setting the FP exceptions build attribute to not use exceptions.
  • --enable-unsafe-fp-math β€” enables optimizations that make unsafe assumptions about IEEE math (e.g. that addition is associative) or that may not work for all input ranges.
🚨 these optimizations let the code generator use some instructions that would otherwise be off-limits (such as fsin on X86). "unsafe" is right there in the name, bestie, i'm just saying 😭
  • --stats β€” prints stats recorded by code-generation passes. numbers go brrr πŸ“Š
  • --time-passes β€” records how much time each pass needs and prints a report to standard error. ⏱️
  • --load=<dso_path> β€” dynamically loads dso_path (a path to a dynamically shared object) that implements an LLVM target. this lets that target name be used with the -march option so you can generate code for it. plug-in energy πŸ”Œ
  • -meabi=[default|gnu|4|5] β€” specifies which EABI version to conform to. valid EABI versions are gnu, 4 and 5. the default value (default) depends on the triple. πŸ¦‹
  • -stack-size-section β€” emits the .stack_sizes section, which contains stack size metadata. the section holds an array of pairs of function symbol values (pointer size) and stack sizes (unsigned LEB128). these stack size values only include the space allocated in the function prologue. functions with dynamic stack allocations are not included. ✨
  • -remarks-section β€” emits the __remarks (MachO) section, which contains metadata about remark diagnostics. πŸŽ€

πŸ’œ Tuning/Configuration Options πŸ’œ

  • --print-after-isel β€” prints the generated machine code after instruction selection. super useful for debugging. πŸ”
  • --regalloc=<allocator> β€” specifies the register allocator to use. the valid register allocators are:
    • basic β€” basic register allocator.
    • fast β€” fast register allocator. it's the default for unoptimized code. ⚑
    • greedy β€” greedy register allocator. it's the default for optimized code. πŸ‘‘
    • pbqp β€” register allocator based on 'Partitioned Boolean Quadratic Programming'. (yes that's the whole name, she's fancy like that 🎩)
  • --spiller=<spiller> β€” specifies the spiller to use for register allocators that support it. currently this option is only used by the linear scan register allocator. the default spiller is local. valid spillers are:
    • simple β€” simple spiller.
    • local β€” local spiller.

πŸ”₯ Intel IA-32-specific Options πŸ”₯

  • --x86-asm-syntax=[att|intel] β€” specifies whether to emit assembly code in AT&T syntax (the default) or Intel syntax. choose your aesthetic πŸ’…

⭐ EXIT STATUS ⭐

if llc succeeds, she exits with 0 πŸŽ‰ otherwise, if an error happens, she exits with a non-zero value 😭 (as she should, honestly).


🌸 SEE ALSO 🌸

lli(1) <lli.html> β€” go say hi 🫢


πŸŽ€ Author πŸŽ€

maintained by the LLVM Team (https://llvm.org/). love them for me πŸ’–


2003-2026, LLVM Project β€” protect her at all costs.


so yeah, that's the whole page babes β€” this was LLC(1), version 21, dated 2026-05-15, and honestly? she ate. go compile something iconic πŸ’…βœ¨πŸŒΈ

πŸ“¦ where this page comes from