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

    <tr>
        <th>Summary</th>
        <td>
            _BitInt implementation does not conform to x86-64 psABI regarding padding bits
        </td>
    </tr>

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

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

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

<pre>
    clang version: 16.0.0
compiler flags: -std=c2x -O2

### Observed behavior

Given the following code:

```c
unsigned char f(unsigned _BitInt(4)* ptr) {
 return *ptr;
}

unsigned char g(_BitInt(4)* ptr) {
    unsigned _BitInt(4) uint = *ptr;
    return uint;
}
```

The generated code for `f` and `g` does not mask out "unused" bits from `*ptr`:

```asm
f:                                      # @f
 movzx   eax, byte ptr [rdi]
        ret
g: # @g
        movzx   eax, byte ptr [rdi]
 ret
```

https://godbolt.org/z/Ev8sbhb84

### Expected behavior

The x86-64 psABI specifies that the unused bits within an object of `_BitInt(N)` type can take unspecified values:

> The value of the unused bits beyond the width of the `_BitInt(N)` value but within the size of the `_BitInt(N)` are unspecified when stored in memory or register.

https://gitlab.com/x86-psABIs/x86-64-ABI/-/blob/3177443c4f5862d48f371d91ab36209f73cfe69c/x86-64-ABI/low-level-sys-info.tex#L297-299

This means that `*ptr` in both cases can have the object representation `0b00010000`, representing the signed/unsigned `_BitInt(N)` value `0`. But according to the generated code this object representation is passed as-is to the returned unsigned char in both cases, which translates to the return value `16`.

As `0b00010000` is a valid object representation for representing the value `0` here, I would expect both functions to return `0` in this case.

In general this requires masking out the unused bits.

### Notes

It looks like the current implementation assumes that valid object representations have all zeroes for the unused bits, and other representations are trap representations.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyMVkFvqzoT_TXOZpTIGELCIovk9uZTpU_3bt7-yeAB_Gpsnm2Str_-aYC0TW5aNUIB7JnjM2fGY2QIurGIO7Y-sPXDQg6xdX5n0Op1mi9Kp152lZG2gRP6oJ1l6R6SfMVXnPEHxveV63pt0ENtZBNodhmiYulDJZ5h-VtMVvO_SKcLfpcB_QkVlNjKk3b-o9n_9AktxBahdsa4s7YNVE4hS_dXaDmfrmp6H-wYioKqlR5qJrZvI38fdHy0kYltxkTBxB766JkogG0OkzN4jIO3wMSeptJ5mG0ePi55vUTDxPYbyADwCREYtI3A0ofbZclnJkQmd-hcYv_I7q8WoUGLXkai6BQJ6IHlvGY5B2kVPTf0rBwGsC5CJ8MTuCECE2KwQ0DFhIBSxwC1dx05zNxy_pn-MnTTSE3p_9aPaoBlvJ7D7dzp9RkAUD4z8QPKl4ikI7D1wSvN1g_vsszSTAMNLThjNdc234V8w7oraRtjT0XNxJGJY-NU6UxcOd8wcXxl4vjztA1lW26z-2X-87nHKn5S5pSu522-zDPow_7wCKHHStcaA8RWxnEDTCmZ8nHWsdUWpAVX_oNVBFdTet5L6hdVYM4hvvQIlbQQ5RNBXHAVnKQZMNzmMf0JxGWcJNDbhUt8cVaNw2etYnuxubv4hFIO8cKXLIN-xS-9pL8mem7RQojOowJtocPO-RdwHjw2OkT0qy-ypKOR5apyHRNHEnhUN8wvebbcHx6ZOC6ZOJbGlUwc02SzybK0yur1Nhcq29bpJlFFIss0F7yoN2lVY15UtxDGnZcGT2iW4SUsta3dKuIzE-n_RbFZiqK4TrcO0KG0c3o_7iyKsXSxhUoGDGPuWnnCUa852R57jwFtlFE7S9685JwnnPOxaMWPdxNqmJPs1HSYOL71ny9SRogs5ys4DBFkVTmvRhw3Qt30lUjB3GemA_QyUPHIsNThAjC1M1Rw3UOvAqcgzq2uWohe2mBkxBv_d65JTmQ_CrwPf6hCZCT5aPUJ23qsqRvdrgSBFj0Ss0c4u8EowHFTT7TrwVaEM9K8HCGz31j7OoyhXRF9tLOcZjLw-O-gPYaxGRMH6sc3m3B1v8H8chHDFXYE49xTAKOfpvqpBu_RRtBdb7B7C1yGMHSXVvOFQmGqRGkMvKKnY4Mku2FH8tDx4mKL_g8A2tzRy_52YrVQu1QVaSEXuEvybcI3gmfFot1lRbXJUWW8SHOVJOu0UFmS5Xxdbcq0UslC7wQXKc94IbjYiGJVK46iLEqVlOlGii3LOHZSm5Uxp44a9kKHMOAuFzwVCyNLNGH85hHC4hnGSSYEfQL5Hfksy6EJLONGhxjeUaKOBnfzHrrV9O1UrZytne-oKK46vMdGTtuql2q8k3qLwZvdHz2sHS49jBafb8veO0oSE8eRMnW1MaT_AgAA___HsgN8">