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

    <tr>
        <th>Summary</th>
        <td>
            [RISC-V] extra `andi` instruction when loading a `bool` atomically
        </td>
    </tr>

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

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

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

<pre>
    When loading a `bool` atomically in C, clang generates an extra `andi` instruction, which I believe is extraneous.

Consider this small litmus test (also at https://godbolt.org/z/TzzxGra86):
```c
#include <stdbool.h>
extern bool active;
bool foo1(void) {
  return __atomic_load_n(&active, __ATOMIC_RELAXED);
}
bool foo2(void) {
  return active;
}
```

With `-O1`, clang generates the following:

```asm
foo1:
.Lpcrel_hi0:
 auipc   a0, %got_pcrel_hi(active)
        ld      a0, %pcrel_lo(.Lpcrel_hi0)(a0)
        lb      a0, 0(a0)
        andi    a0, a0, 1
        ret

foo2:
.Lpcrel_hi1:
        auipc   a0, %got_pcrel_hi(active)
        ld      a0, %pcrel_lo(.Lpcrel_hi1)(a0)
 lbu     a0, 0(a0)
        ret
```

The atomic load version does an extra `andi` rather than just `lbu` as in the non-atomic version.

It seems GCC used to do this as well, but it was fixed (reference below).

References:
 - old GCC bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97417
Comparison's with the same litmus test as that bug report:
 - clang trunk comparison (extra `andi`): https://godbolt.org/z/1nzdxT64v
 - GCC 14.2.0 comparison (identical output): https://godbolt.org/z/75fjrxa45
 - GCC 8.2 comparison (also has extra `andi`): https://godbolt.org/z/9Y6osTqqP
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0VU-P4rgT_TTmUiJyHELIIQeGbkYtzU_zU29rZ_eEnLhI3OvYjP8Aw6dfOcl00-zMTl8WISzsqlf1yn5V3DnZasSK5B9IfjfjwXfGVtxwj25WG_Gt-tKhBmW4kLoFDmRJa2MUWVLg3vSy4Up9A6lhQ9gGGsV1Cy1qtBEBuAY8ezu4cS1kdJPaeRsaL42OLqdONh08QI1K4hFButFFowkuIXRN6HpjtJMCLfhOOnA9VwqU9H1w4NF5IGzFlTPAPXTeHxzJ1oRtCdu2RtRG-cTYlrDthbDt0-Vy_mj5aklYGc3omizp-G3iH5ZJ3aggEEi2cV5EsklHsntC13j2aDXELeCNl0ck2QdC18PG3piUsNXRSEFYCaSIJwAWfbAadruxWrtYyZ0mbEXYcsJgG9jt1k-f__ew2T3ef1r_cX83JBcBSHF3FYD9PMB1PqPTC6-xhl-k7-I1zD-nce8Hl-U7hL1RypykbqfaXMFw1xO6HmgOZ8mnQ2NR7TpJxw3gQR4aAOADPGF5a_zuu1G8o4lvOSQ-fpQY1xef0V4ZwlbXEVgZAeiNc33tTH9gER_dq8X4m16dW_QjzaG6N7wmoi9Y_xm99IaeqsMveE15v73ipw4nUQ6ChSNaJ40GYX4iRct9N6iKa3gOUUhLquowiNtFUccnoY2eT6gT4KTKBw8OsXfwcbOB4FCANyDMKFLu4IRKxfzr4EF6OHEHe3lGEeVqcY8WdYNR9-ZEWDmBPn4_cFPx52CUGELUoQWLB2M9yda3Qm-apNVhEnod2otUihO2dZ057erQJk0rSbaVgmR3ZbFIi6Gt9AdupYuNqHBwigqJjB3v8U1_4VEc3L_NYExuFJG3Qf8FzQtepHhb7bHh_LJBpfoizk_LxXHEj8TTRcISegMvBWof2y-Y4A_BvxO-yPfP9swX-Sv8KmE32EMz7bj7x4t5Z5Dyz6VxT1-__n8mqkyUWclnWKXFgtEiz_J01lW4X67yrMRFti_3WbESXGS5wKxAUfL9is9kxSjLaZbmLF2UaZo0JS8yzva0zilmaU4WFHsuVaLUsY-xZ9K5gFWapYtiOVO8RuWGucaYxhMMp4SxOOZsFZ3mdWgdWVAlnXevMF56NQzEx4ffNvPfSX73rzMMTu8YkLNgVXVTNem7UCeN6QnbxuDTMj9Y84yNJ2w7pOzimxg5HSv2dwAAAP__UftWPA">