Builtin functions

Implements and registers compiler builtin functions in the Carbon toolchain.

33.9k|1.7k|Updated Apr 27, 2020
One-click install
npx skills add https://github.com/carbon-language/carbon-lang --skill builtin-functions
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: Builtin functions
Source: https://github.com/carbon-language/carbon-lang/tree/main/.agents/skills/builtins
Command: npx skills add https://github.com/carbon-language/carbon-lang --skill builtin-functions

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Adding a new builtin function to the Carbon compiler requires coordinated changes across five separate toolchain areas (kind registration, signature validation, constant evaluation, LLVM lowering, and prelude bindings), and missing any step causes build or runtime failures. This Skill provides the complete workflow and C++ patterns to implement builtins correctly.

Core Features & Use Cases

  • Five-Step Integration Workflow: Register the builtin kind in builtin_function_kind.def, declare signature constraints in builtin_function_kind.cpp, wire constant evaluation in eval.cpp, map LLVM lowering in handle_call.cpp, and bind prelude interfaces under core/prelude/.
  • Constant Evaluation & Diagnostics: Implement compile-time execution with llvm::APInt/APFloat, emit typed diagnostics from kind.def, and enforce fast-path range limits to prevent compile-time memory exhaustion.
  • Testing Conventions: Author checker and lowering test splits under toolchain/check/testdata/builtins/ and toolchain/lower/testdata/builtins/ using minimal preludes and direct builtin calls.
  • Use Case: When adding an int-to-float conversion builtin, follow the guide to register IntConvertFloat, validate its signature with AnyInt/AnyFloat constraints, implement compile-time conversion, lower it to SIToFP/UIToFP LLVM instructions, and bind it in the prelude.

Quick Start

Ask the AI to walk you through adding a new builtin function to the Carbon compiler, from kind registration through LLVM lowering and prelude binding.

Frequently Asked Questions about Builtin functions

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I add a new builtin function to the Carbon compiler?

Adding a Carbon builtin requires five steps: register the kind in builtin_function_kind.def, declare its signature constraint in builtin_function_kind.cpp, wire constant evaluation in eval.cpp, map LLVM lowering in handle_call.cpp, and bind it in core/prelude Carbon files.

How do I implement compile-time constant evaluation for Carbon builtins?

Handle the builtin case inside MakeConstantForBuiltinCall in eval.cpp, confirming the phase is Phase::Concrete. Use llvm::APInt, APFloat, and APSInt for high-precision math, and return SemIR::ErrorInst::ConstantId on invalid input.

How are Carbon builtins lowered to LLVM IR?

Runtime-eligible builtins are mapped inside HandleBuiltinCall in handle_call.cpp to LLVM IR builder methods such as CreateSIToFP or CreateUIToFP. Compile-time-only builtins assert with CARBON_FATAL since they must never reach code generation.

Why must Carbon builtin tests use a minimal prelude?

Builtin tests must isolate compiler builtins from the library prelude, so they use the min_prelude primitives file and declare builtins directly. Standard operators are unavailable in minimized preludes, so tests call primitive builtins like float.add explicitly.

Where do prelude implementations for literal type conversions live in Carbon?

Carbon's orphan rules require impls between literal types like FloatLiteral and IntLiteral to reside in as.carbon, since literals have no backing source file. Sized conversions for Int(N) or Float(N) belong in their respective type source files like int.carbon or float.carbon.