<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/93651>93651</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [AArch64][FMV] Incorrect SVE detection on SVE2 cores with FMV
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          kinoshita-fj
      </td>
    </tr>
</table>

<pre>
    # Problem

Compiling the following program using FMV with `-rtlib=compiler-rt` and running it on cores supporting SVE2 results in the execution of the default function.
This indicates that the `target_version("SVE")` attribute is not being correctly detected on SVE2 cores, because SVE2 contains SVE. However, the detection appears to be accurate on SVE-only cores.

```c
#include <stdio.h>
#include <stdlib.h>


__attribute__ ((target_version("sve")))
void func1(void){
 printf("SVE\n");
}

__attribute__ ((target_version("default")))
void func1(void){
        printf("not SVE\n");
}

int main(int argc, char **argv){
 func1();
        return 0;
}

```

# Expected behavior

On SVE2 cores and SVE cores:

The func1 with `target_version("sve")` should be executed. And it should print `SVE`.

# Actual behavior

On SVE2 cores:

The func1 with `target_version("default")` is executed instead. And it printed `not SVE`.

On SVE cores:

The func1 with `target_version("sve")` is executed correctly. And it printed `SVE`.

# Environment

At least Clang 18.1.2 and the latest main branch (commit b80d982a62676314ec93dc8881b9f8957217192).

# Cause
The most likely cause is that the conditions to determine SVE support are incorrect.

They are used at `__init_cpu_features_constructor` function which is generated when FMV features.

[`llvm-project/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/mrs.inc`](https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/mrs.inc#L133-L147)

```
 // ID_AA64PFR0_EL1.SVE != 0b0000
    if (extractBits(ftr, 32, 4) != 0x0) {
      // get ID_AA64ZFR0_EL1, that name supported
      // if sve enabled only
      getCPUFeature(S3_0_C0_C4_4, ftr);
      // ID_AA64ZFR0_EL1.SVEver == 0b0000
      if (extractBits(ftr, 0, 4) == 0x0)
        setCPUFeature(FEAT_SVE);
      // ID_AA64ZFR0_EL1.SVEver == 0b0001
      if (extractBits(ftr, 0, 4) == 0x1)
 setCPUFeature(FEAT_SVE2);
      // ID_AA64ZFR0_EL1.BF16 != 0b0000
 if (extractBits(ftr, 20, 4) != 0x0)
 setCPUFeature(FEAT_SVE_BF16);
    }
```

# Possible Fix

Cores that support SVE2 also support SVE. The code should be modified as follows.

```diff
    // ID_AA64PFR0_EL1.SVE != 0b0000
    if (extractBits(ftr, 32, 4) != 0x0) {
      // get ID_AA64ZFR0_EL1, that name supported
      // if sve enabled only
 getCPUFeature(S3_0_C0_C4_4, ftr);
-     // ID_AA64ZFR0_EL1.SVEver == 0b0000
-     if (extractBits(ftr, 0, 4) == 0x0)
 setCPUFeature(FEAT_SVE);
      // ID_AA64ZFR0_EL1.SVEver == 0b0001
 if (extractBits(ftr, 0, 4) == 0x1)
        setCPUFeature(FEAT_SVE2);
 // ID_AA64ZFR0_EL1.BF16 != 0b0000
      if (extractBits(ftr, 20, 4) != 0x0)
        setCPUFeature(FEAT_SVE_BF16);
    }
```

A similar [issue](https://github.com/ARM-software/acle/issues/320) is posted in the ACLE, but it is not yet fixed.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzcV01v47AR_TX0hbBAUbZsHXxwbAtdIEGDTZrDXgSKGlncpUiDpJzk3xek5FhOk80m3V4aGFL4OU-PM2-GzFqxVwArNL9C8-2Eda7RZvVLKG0b4di0_jkpdfW8QjTBt0aXElpEtois--dGtwchhdpj1wCutZT60bcORu8Na3FnfSu_ecCPwjUYpWRqnBQlSrY8LAUzNQ6lBDNVYdMp5ecLh7XCXBuw2HaHgzbOd9897Cg2YDvpLBYqmIQn4J0TWmFdh44KatZJh-tOcd8f9UDvG-HXVIIzBxa7hrkwHaXEMbMHVxzBWKEVoktE6d3DDlGKaBagOWdE2TnAwmKlHS7Bw-HaGOBOPuMKHHAHlUcdQAboiG5wCZx1Fk69yjGhrG9F-B_6EY5g_Kwet9_Dfwg7HIAZi53GJWDGeWeYg2HvqVbyud8_Gh8ESkn_40ObJkJx2VWAUbKxrhI6alCye2dUinI8PHoWxcvnFwUO7CzfYsweYWCs_4XFRy2qcBIxokvf8COLq34QH4xQrj4TPt-oYYtkmIIW269gGXzgs3iGvzEsf9p_BE0oh1smPAD_LzN77k-WN8xgRNeIrpnZHy_MnXCMdz1hMOA6ozB5z9zLcV900gTvng69K5bQsKPQZjzhn2P3DBF397AbnDW5OPV7H80e30vc_v7MU4Jtozvp7Q4xCVWE16rywTwMBWL9Xp7RlESvsa-565j8GPmXsF76REp8LJ-AYqGsA3YGHJBC5fc6ecArvD2gv8XdGMuLrLyF5h3mduoojFYtKDceWjssgVmHN5KpPY6XURzRcO5ecaRXwt5rcWmY4o0PKa7bVjhcLkmVLSlLabpIk3gGPEsqvlwu4zKrl9l8QeNFnHn8_wFm4xXvTEWrrcNS_AKvW0EMxUh_uVaV8LIX9M6LoGmFCoJ5kn7MDGChBl6iV1Q_h-HOQoVZcK6iEEq4gh-6ogbmOgO24FpZZzrutPF0n3IDfmwEbzyePSjwKlvhxwZUSFinxZffN79CKZHy2E4PRv8E7hDNx5mM5j670bzshHRCWT986IpWVyARzRkzvElniOZ1e0Q0b42NhOI-kOdbRJeNc4fgTzRHNN8L13RlxHXr95XH02tku5Tam-ul528gocl1nCTT63i2eJHNNzUH9xjxt22xXqez2_w7KXbXceRPDtEYJVtMSkIIOSubqL2HwZMzjLsr4Syiy9qFFJhQ_5whmr0sfiKhdSnPg9E9uJPhH4PhPpEyhxVr4eQ7UL2xWNTYHgGDYqUMSVs-j2ftwW1u_5X3x4_o8i4pSLEhxWZWzLyRgPi1ZF-S8WNExhEMRsn2LT5-ywg5EzKsDoRc5gn7Cmu-W98XoXj5OsD46wDjM8D3kNE_hnaVx-mbnvQbTJS87UYfgCq8rdfAzin3vWR7q60VpQSci6fLqticasyThoXsxaTV454I3wcJrGCUPVtdiVp4ObNDQf1OpVeJuh6h_f-Lxk8G4vRrgTj97wLxfxmBXw6-D9ThMgY_G34f8fVBDH6A7QuhuMZWtEL6Snt-Jazt4MNkuv5-M7W6do_MG88Zl_4V1vpEmdDg7cLig7Z9gRiqlfXmeheudZ3zhdlwHXwGh2vxBFU0qVZJlSUZm8AqXsRpliYkySbNKsnYfJ7WkJXpgvKkrHhJFmUVpzXENcBsIlaU0BmZ04ykMUmyKM4Y4THE1axiCZulaEagZUJGvgCItNlPAtpVlqTzeCJZCdKGWzylCh5xTwOl_lJvVqFoKLu9RTMihXX2vIsTTobr_3rdFwTzLZpf5TcPaL7F305VV6jHzlfUi3tuX-bmNw-TzsjVpyuYF9L7Lzmu6L8DAAD__2SQxuw">