<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Implement __builtin_zero_non_value_bits which was recently added to MSVC for P0528R3 and P1123R0"
   href="https://bugs.llvm.org/show_bug.cgi?id=46685">46685</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Implement __builtin_zero_non_value_bits which was recently added to MSVC for P0528R3 and P1123R0
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>10.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++2a
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>gutenev@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>MSVC implements __builtin_zero_non_value_bits intrinsic.

This is needed to implement C++2a features:
* P0528R3 Atomic Compare-And-Exchange With Padding Bits
* P1123R0 Atomic Compare-And-Exchange With Padding Bits For atomic_ref

__builtin_zero_non_value_bits non-atomically zeros non-value bits in types such
as 

struct X
{
    int a;
    char b;
    // 3 bytes padding for 32-bit int
};

or

struct Y
{
    int a: 7;
    // 25 bits of padding for 32-bit int
};


For std::atomic it can be used in constructor and in store and exchange.
So compare_exchange_* would be able to use bitwise comparison, as non-value
bits are always zeros


For std::atomic_ref non-atomically zeroing in constructor is apparently not an
option due to possible concurrent atomic_ref instances.
Still, __builtin_zero_non_value_bits can be used.
For lock-free atomics, compute the mask as follows:

target_type v;
memset(&v, 0xff, sizeof(v));
__builtin_zero_non_value_bits(&v);
integer_type value_mask;
memcpy(&value_mask, &v, sizeof(v));

Then implement compare_exchange as follows:

for(;;)
    integer_type prev = _InterlockedCompareExchange(
                           &val, desired, expected);
    if (prev == expected) {
        return true; // Success
    }

    if ((prev ^ expected) & value_mask) {
        break; // Failure due to value bits mismatch, fail
    }

    // Failure due to only padding bits mismatch
    // Retry with new expectation for padding bits
    expected = (expected & value_mask) | (prev & ~value_mask);
}

For lock-based atomic_ref just apply __builtin_zero_non_value_bits both to
target (under the lock) and comparand (possibly not under the lock)

std::atomic_ref method can also be used for std::atomic too for unification.

Note that:
* In atomic_ref method, the computation of mask should defacto result in
value_mask computed by compiler in case of optimization enabled
* In atomic method __builtin_zero_non_value_bits should also work in compile
time in constexpr constructor</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>