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

    <tr>
        <th>Summary</th>
        <td>
            Clang source-level coverage profiling instrumentation does not honor the attribute naked
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang:codegen,
            coverage
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          miyuki
      </td>
    </tr>
</table>

<pre>
    Clang source-level instrumentation (the `-fprofile-instr-generate` option) does not honor the function attribute `naked` and generates a prologue that might interfere with the function body. For example, the following code

```C
extern "C" __attribute__((naked))
void semihost(unsigned op __attribute__((unused)),
              unsigned int* c __attribute__((unused))) {
  __asm(
    "PUSH {R4, LR}  \n"
    "SVC #0xab     \n"
    "POP  {R4, PC}  \n"
  );
}
```

When compiled with the current trunk build of Clang, using the flags `-target arm-none-eabi -march=armv8-a -O -fprofile-instr-generate` produces the following LLVM IR for the function `semihost`:

```
define dso_local void @semihost(i32 noundef %0, ptr noundef %1) #0 {
  %3 = load i64, ptr @__profc_semihost, align 8
  %4 = add i64 %3, 1
  store i64 %4, ptr @__profc_semihost, align 8
  tail call void asm sideeffect "PUSH {R4, LR}  \0ASVC  #0xab \0APOP  {R4, PC}  \0A", ""() #1
  unreachable
}
```

Which, in turn, gets compiled into the following assembly:

```
semihost:
 movw    r0, :lower16:.L__profc_semihost
        movt    r0, :upper16:.L__profc_semihost
        ldrd    r2, r3, [r0]
        adds r2, r2, #1
        adc     r3, r3, #0
        strd    r2, r3, [r0]
 push    {r4, lr}
        svc     #171
        pop     {r4, pc}
```

This is incorrect because the function parameters are passed in the registers r0 and r1, and they get overwritten.

I think the correct behavior would be not to instrument naked functions, similarly to how it is done for IR-level coverage: https://github.com/llvm/llvm-project/pull/108552
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyUVklv4zgT_TX0pWCDpiQvBx8cB8HXQD50kJ7pORoUWZI4oUiBi9359wNS3pJOZ6YNAjLIqlfLe1y496o1iBtS3ZHqfsJj6Kzb9Oo1vqhJbeXrZqe5acHb6ARONR5QgzI-uNijCTwoa4CwVegQyIJOm8HZRmmcZptpiwYdD0gWFOyQjAlbg7TowdgAnTXWQfJtohEZi4fgVB1DhjP8BWXy5UbCGcsDh8FZbduIEDoeoFdtF0CZgK5Bh3BUoXuLmiqZwYN1gD94P2gkbDdaWK3tUZkWhJVI6DaNBR3HjtAt_gjoUolsRxiD_f6S4H5P2Iqw1ZgkW6dBtwerJHjsVWd9IGwVTe6wBDt85BxN9BdvlgLCm9_FXZlA2BbEv4OsgSzvMtB-z32fTEZUwtjTn9_-l5afy9SAx2eyvAcg1c4Qxq5W377vgLCC_uB1TuIng6evT3CFedr9BJMSKVISZHl_29GxwX91aEDYflAa5ZUtEZ1DEyC4aF6gjkpLsA1kAaY40SeeMmuatz7rLXDXYgDu-qmxBqfIawXTnjvRkeKeu_6wmnKYfoXPlDk4K6NA_04Rj4_f_w9fnqF5r1GyoBeGF5QU23e6IXQrsVEGQXq711ZwDVkXpKQ30lAFA2OjkdgAYRVNNQ7B3c7NM52soBdOCasKIMU9aMslqEV59iIl3e9TjWJ_jbEDrlVrYHX2LbMvl9k1gyWjeV72wTo8z_8ObuBKg-D6VCX3PXglEZsGRfhMdnSbpHbRWp75lbboNomLJWWyPFan3ozJR-OQi47XGn8tOyW6hKAMhOhM-tti8FcpKhPsOxFw77Gv9euHLF8akheht4dj2iEuU0mKrbZHdPMFKbazx5-aeN3qvT2EN35xGP6Ln5ZOZr_cF5epJNWdo6S6vzHjUvqzzamDp6ad10X-jgAnGFbQGxMfPo80RN_ls2F55zJv2o0UXAAOY4wUenkbfLADvPEcxIfk_dEpD2kYYZ1LuqpR8Ojx7dYcuOM9BnQeuEMYEn0yE94hOGyVz2tuvFLcPEvZyLT8msQA9oDu6FQIaGZj5C8QOmVexiPqErvjB2UdHG3UEmrM11mwN1cj5HvhkplPkbzqleZOvybTzh5BhVSTtAbzKfPl-XTDipQGb5EUW-hCGHxSGHsg7KFVoYv1TNiesAetD-fPdHD2bxSBsIchak3Yw5yuqopN5KaQ62LNJ7iZL4v1irIFnU-6jRRrpKuyWVBaVUssSkGrNW-aei2EFGI1URtGWUXZfDkvC0rprC7LChdzLudcsKKRpKTYc6VnKf7MunaivI-4mbNluV5NNK9R-_yyYEzkQ7zYplu2RTNu5TR_LpSx9P5wm1xLHVtPSqqVD_6KHlTQ-NF75AwC4xGftu37J8oHT47rSyMzNYlOb36717lin7o9Fn3YsH8CAAD__yYS2JA">