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

    <tr>
        <th>Summary</th>
        <td>
            __builtin_assume worsens codegen
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            llvm:optimizations,
            missed-optimization
      </td>
    </tr>

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

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

<pre>
    2 versions of the `GetTag` that differ only by presence of `__builtin_assume`:
```
enum class Tag : uint8_t {
  kNormal = 0x4,
  kNonNormal = 0x3,
};

constexpr uintptr_t kTagShift = 42;
constexpr uintptr_t kTagMask = uintptr_t{0x7} << kTagShift;

inline Tag GetTag1(void* ptr) {
  auto res = static_cast<Tag>((reinterpret_cast<uintptr_t>(ptr) & kTagMask) >> kTagShift);
  __builtin_assume(res != Tag::kNonNormal);
  return res;
}

inline Tag GetTag2(void* ptr) {
  auto res = static_cast<Tag>((reinterpret_cast<uintptr_t>(ptr) & kTagMask) >> kTagShift);
  return res;
}

void Rest(void* ptr);

void Foo1(void* ptr) {
  if (static_cast<uintptr_t>(GetTag1(ptr)) & static_cast<uintptr_t>(Tag::kNormal))
    __builtin_trap();
 Rest(ptr);
}

void Foo2(void* ptr) {
  if (static_cast<uintptr_t>(GetTag2(ptr)) & static_cast<uintptr_t>(Tag::kNormal))
    __builtin_trap();
 Rest(ptr);
}
```

Without `__builtin_assume` clang emits a single `BT` instruction (good), with `__builtin_assume` it emits `MOV`+`SHR`+`TEST` and consumes 1 more register:

```
Foo1(void*): # @Foo1(void*)
        movq    %rdi, %rax
        shrq    $42, %rax
        testb   $4, %al
        je      Rest(void*)@PLT # TAILCALL
        ud2

Foo2(void*): # @Foo2(void*)
        btq     $44, %rdi
        jae Rest(void*)@PLT                   # TAILCALL
 ud2
```

https://godbolt.org/z/arE5v5qGK
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMVk1z4jgQ_TXNRZWU3DLYHHwgEGa3NrO7NaF2j5SMhdHElhipzSTz67ckCGCSsHMcV8of6dfq915LXUjvdW2UKmB4B8PZQHa0sa6odi_dk90NSlu9FMh2ynltjWd2zWijGIz4J0ULWcOIM9pIYpVer5Vj1jQvrHxhW6e8MisVEmDEl8uy0w1ps5Ted62CEQcxAT4DPgnv-7_4qUzXslUjvWcLWTMQE9ZpQ_mSGGR3ewxjT39a18qGgZgx_pwCTs8iphcUxyBkMxCHJfb3lTWe1PPWxRpbcktiTwtZP270mmJ-iseUj8CfpX-K2OO_IbvjzxlkMwZiCmJ6WvOivjaNNioK3fuZAOY7qyvACduSAxyfq5YdWeaUj9U8SdKr5Up6AjENvRD3gDlg7pQ2pNzWKXoNn6hF0OvSODoqiN_iHsT9GVscHwkz9qaJoZJngEmgEwlMQExODeinO0WdM4H-yYRsdtUN_IXd-H85gTn7ojy9UXGxCyJwbu315us1A8z7Oi-EnPbQoc5B1dWk88a9dg3Hr1XP205ObqOnZz4c9F3qeseJubXX-_nTAvFXEtifXvv7v5o2tqMPJl-YbqZmqtXkmWRem7qJI_VuEaLaeHLdirQ1wY_a2ioynrLvmjYfranpsCCM-Oe__gmE8A5G_PG3L8f3xf1jrCBNxcIw61rlWcJa6xRzqtaelDuN5ffk9TdpNGTCAAWDlL-NHR0OV2t338ITcOgqHeSEN_ncR_mNO6DSFD8CkfJUHkAHjGz6kK9q_-wfv0Aq5X8_LCLnxeT3h-nk4aGf2VV4bkB_175RjFcUlxSlRJqvPIP0PlGpPiT59nqH9onveztxQ7T1oac4B5zXtiptQ7fW1YDzH4Bz6e6Hu-G3T38MqkJUYzGWA1UkWZLwhA8RB5siKXM-5LniWcrXqcBhLjJVivUwEWORi_VAF8gx5QITnqfI8TZVfJRkZbbO5RjTsYCUq1bq5rZpdm2oPdDed6rIRwnng0aWqvHx5wdiQICY2C3pVv-Q4Qx4wLARALHV3qvq5jwYYsPZwBUh8absag8pb7QnfypGmhpVXJ4Z9t06r4xnK1upWplB55riwi1Nm668XdkWcB6Z7R83W2e_qhUBzqMQDziPWv4LAAD__3LVrGc">