Function Multiversioning (Using the GNU Compiler Collection (GCC))

### 8.8 Function Multiversioning ¶

Function multiversioning is a mechanism that enables compiling multiple versions of a function, each specialized for different combinations of architecture extensions. Additionally, the compiler generates a resolver that the dynamic linker uses to detect architecture support and choose the appropriate version at runtime.

Function multiversioning relies on the indirect function extension to the ELF standard, and therefore Binutils version 2.20.1 or higher and GNU C Library version 2.11.1 are required to use this feature.

There are two versions of function multiversioning supported by GCC.

For targets supporting the `target_version` attribute (AArch64, LoongArch, and RISC-V), when compiling for C or C++, a function version set can be defined by a combination of function definitions with `target_version` and `target_clones` attributes, across translation units.

For example:

    // fmv.h:
    int foo ();
    int foo [[gnu::target_clones("sve", "sve2")]] ();
    int foo [[gnu::target_version("dotprod;priority=1")]] ();

    // fmv1.cc
    #include "fmv.h"

    int foo ()
    {
      // The default version of foo.
      return 0;
    }

    // fmv2.cc:
    #include "fmv.h"

    int foo [[gnu::target_clones("sve", "sve2")]] ()
    {
      // foo versions for sve and sve2
      return 1;
    }

    int foo [[gnu::target_version("dotprod")]] ()
    {
      // foo version for dotprod extension
      return 2;
    }

    // main.cc
    #include "fmv.h"

    int main ()
    {
      int (*p)() = &foo;
      assert ((*p) () == foo ());
      return 0;
    }

This example results in 4 versions of the foo function being generated, and a resolver which is used by the dynamic linker to choose the correct version.

For the AArch64 target GCC implements function multiversioning, with the semantics and version strings as specified in the Arm C Language Extensions (ACLE).

For targets that support multiversioning with the `target` attribute (x86) a multiversioned function can be defined with either multiple function definitions with the `target` attribute (in C++) within a translation unit, or a single definition with the `target_clones` attribute.

Here is an example.

    __attribute__ ((target ("default")))
    int foo ()
    {
      // The default version of foo.
      return 0;
    }

    __attribute__ ((target ("sse4.2")))
    int foo ()
    {
      // foo version for SSE4.2
      return 1;
    }

    __attribute__ ((target ("arch=atom")))
    int foo ()
    {
      // foo version for the Intel ATOM processor
      return 2;
    }

    __attribute__ ((target ("arch=amdfam10")))
    int foo ()
    {
      // foo version for the AMD Family 0x10 processors.
      return 3;
    }

    int main ()
    {
      int (*p)() = &foo;
      assert ((*p) () == foo ());
      return 0;
    }

In the above example, four versions of function foo are created. The first version of foo with the target attribute "default" is the default version. This version gets executed when no other target specific version qualifies for execution on a particular platform. A new version of foo is created by using the same function signature but with a different target string. Function foo is called or a pointer to it is taken just like a regular function. GCC takes care of doing the dispatching to call the right version at runtime. Refer to the GCC wiki on Function Multiversioning for more details.