# Learn about function multiversioning

## In this learning path

- [Introduction](https://learn.arm.com/learning-paths/cross-platform/function-multiversioning/)
- [About function multiversioning](https://learn.arm.com/learning-paths/cross-platform/function-multiversioning/semantics/)
- [Example 1 - code generation](https://learn.arm.com/learning-paths/cross-platform/function-multiversioning/examples/)
- [Example 2 - runtime using ACLE intrinsics](https://learn.arm.com/learning-paths/cross-platform/function-multiversioning/examples2/)
- [Example 3 - inline assembly at runtime](https://learn.arm.com/learning-paths/cross-platform/function-multiversioning/examples3/)
- [Compatibility with streaming mode](https://learn.arm.com/learning-paths/cross-platform/function-multiversioning/streaming-mode/)
- [Further information on implementation](https://learn.arm.com/learning-paths/cross-platform/function-multiversioning/implementation-details/)
- [Changes from released compilers](https://learn.arm.com/learning-paths/cross-platform/function-multiversioning/changes-from-past-releases/)
- [Next Steps](https://learn.arm.com/learning-paths/cross-platform/function-multiversioning/_next-steps/)

## About this Learning Path

| Skill level:      | Advanced      |
|-------------------|---------------|
| Reading time:     | 1 hr          |
| Last updated:     | 06 Jul 2026   |

| Author:                | Alexandros Lamprineas, Arm                               |
|------------------------|---------------------------------------------------------|
| Arm IP:                | [Cortex-A](https://support.arm.com/?tab=compute-ip&Product%20Type=Application%20Processors) [Neoverse](https://support.arm.com/?tab=compute-ip&Product%20Type=Infrastructure%20Processors) |
| Tags:                  | [Performance and Architecture](https://learn.arm.com/tag/performance-and-architecture) [Linux](https://learn.arm.com/tag/linux) [Android](https://learn.arm.com/tag/android) [macOS](https://learn.arm.com/tag/macos) [C](https://learn.arm.com/tag/c) [CPP](https://learn.arm.com/tag/cpp) [Runbook](https://learn.arm.com/tag/runbook) |

### Who is this for?
This is an advanced topic for developers interested in optimizing their C/C++ applications across Arm64 targets.

### What will you learn?
Upon completion of this Learning Path, you will be able to:
- Use hardware features to tune your applications at function level.
- Create multiple versions of C/C++ functions for the targets that you intend to run applications on.
- Assist the compiler in generating optimal code for the targets, or provide your own optimized versions at source level.
- Automatically select the most appropriate function version at runtime.
- Reuse your optimized application binaries across various targets.

### Prerequisites
Before starting, you will need the following:
- Basic knowledge of GNU function attributes.
- Familiarity with indirect functions (ifuncs).
- Basic knowledge of loop vectorization.
- Familiarity with Arm assembly.
- A LLVM 20 compiler with runtime library support or GCC 16.

### Summary
You’ll implement function multiversioning for arm64 in C/C++ using the `target_version` and `target_clones` attributes, so a single binary contains feature-specific implementations. You’ll create versions keyed to architectural features such as `default`, `sve`, `sve2`, `simd`, `mops`, and `sme2` to enable runtime selection of the most suitable function. Through hands-on examples, you’ll compare code generation for a vectorized loop, write an SVE-based dot product with Arm C Language Extensions (ACLE), and mix SVE2 inline assembly with library calls where the compiler can emit `FEAT_MOPS` for `memcpy`. You’ll also cover streaming mode compatibility by keeping calling conventions consistent across function versions.

### Frequently asked questions

<details>
<summary>How do I know which function version executed at runtime?</summary>
In the dot product example, the SVE-specialized function prints a message when it runs. If that message doesn’t appear, the default version executed.
</details>

<details>
<summary>Which option should I use in `target_version` or `target_clones`?</summary>
Use architectural feature names shown in the examples, such as `default`, `sve`, `sve2`, `simd`, `mops`, or `sme2`. You can also combine multiple features using a `+` separator in the attribute string.
</details>

<details>
<summary>Does the order of entries in `target_clones` affect selection?</summary>
No. The order of versions listed in `target_clones` doesn’t affect which version is chosen at runtime.
</details>

<details>
<summary>How should I organize code that uses ACLE intrinsics or inline assembly?</summary>
Place SVE or SVE2-specific code in functions annotated with the corresponding `target_version` (for example, `sve` or `sve2`). Keep a generic `default` version so the binary runs on Armv8 targets without those features.
</details>

<details>
<summary>What should I check if I use streaming mode with multiversioning?</summary>
Ensure every version of the function uses the same calling convention. The examples show combining `__arm_streaming` (and related attributes) with `target_version` or `target_clones` to keep versions compatible.
</details>
