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

    <tr>
        <th>Summary</th>
        <td>
            x86 `bt` instruction emission can be improved
        </td>
    </tr>

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

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

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

<pre>
    The following four functions are examples where the `bt` instruction can be used during code generation:

<details>
<summary>LLVM</summary>


```LLVM
define noundef zeroext i1 @bit_test_0(i64 noundef %num, i64 noundef %shift) unnamed_addr {
start:
  %mask = shl nuw i64 1, %shift
  %bit = and i64 %mask, %num
  %bool = icmp eq i64 %bit, 0
  ret i1 %bool
}

define noundef zeroext i1 @bit_test_1(i50 noundef %num, i50 noundef %shift) unnamed_addr {
start:
  %mask = shl nuw i50 1, %shift
  %bit = and i50 %mask, %num
  %bool = icmp eq i50 %bit, 0
  ret i1 %bool
}

define noundef zeroext i1 @bit_test_2(i128 noundef %num, i128 noundef %shift) unnamed_addr {
start:
  %mask = shl nuw i128 1, %shift
  %bit = and i128 %mask, %num
  %bool = icmp eq i128 %bit, 0
  ret i1 %bool
}

define noundef zeroext i1 @bit_test_3(i20 noundef %num, i20 noundef %shift) unnamed_addr {
start:
  %mask = shl nuw i20 1, %shift
  %bit = and i20 %mask, %num
  %bool = icmp eq i20 %bit, 0
  ret i1 %bool
}
```

</details>

<details>
<summary>Generated assembly </summary>


```asm
bit_test_0:                             # @bit_test_0
        bt      rdi, rsi
        setae   al
 ret
bit_test_1:                             # @bit_test_1
        mov rcx, rsi
        mov     eax, 1
        shl     rax, cl
        and rax, rdi
        shl     rax, 14
        sete    al
 ret
bit_test_2:                             # @bit_test_2
        mov rcx, rdx
        xor     eax, eax
        mov     edx, 1
        xor r8d, r8d
        shld    r8, rdx, cl
        shl     rdx, cl
        test cl, 64
        cmovne  r8, rdx
        cmovne  rdx, rax
        and r8, rsi
        and     rdx, rdi
        or      rdx, r8
        sete al
        ret
bit_test_3:                             # @bit_test_3
 mov     ecx, esi
        mov     eax, 1
        shl     eax, cl
 and     eax, edi
        test    eax, 1048575
        sete    al
 ret
```
</details>

Currently, LLVM only emits `bt` if the integer bit width is exactly that of a register. Other integers do not get this treatment. The 128-bit integer example is particulary important since it can be easily created using Rust/C (`u128`, `__int128`) while being quite slow.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJysVk9v27gT_TT0ZVCDov5YOeiQJvXv0h8WWBR7DShxZHFLkS45iu399AtKtiu77iZGawggwnnzyPeGmIwMQW8sYsXyjyx_XsiBOuerL8_YfNV2s6idOlRfOoTWGeN22m6gdYOHdrANaWcDSI-Ae9lvDQbYdegRqENgBa-JFRy0DeSHEQyNtFAjDAEVqMFHtsYphA1a9DJCWPrI-PilTwpJahNY-mn6Owx9L_2BpZ8-f_7r_yx9YmL9fe-Yxh9ZwadvRPFHha22CNYNVmEL_6B3uCfQCbCM15peCAO9cCZKXWRnGBO5HXomnuBqN3S6JSYeYLBW9qhepFIe2Ooj44-BpKdJAkRsL8NXYOkzhM6AHXYjVxJJz0RHZK1pBEqrRtAx-QiNNzkBnTMjUjf9FvDbCV1rimA-4jxO-iZ49GT1PJnzPjOSaEbOb5lxuftrZuT8HWbk_B4zJvRvNUNEMxJR3nLjavvX7Ihkb_sRUXcYcoT_VkfS6Ii4-TzEb3we4j3PQ9z1PMT7n8epi5zbERPry470RpP639TUUIEMAfvaHODtniVDvP2sK6WP8F8_JtKrNsbPCTVNq1c6yvVBz4IBSSIAyCg5mjA_Nrn32GTG3LtX8M3-xyNjIP5QjsF5Tqz5eNUp1JhZLJb5uB-V_DQpyS7lIfxMnrhXnviJPLWfBfbOz-XF5YZ29YP2mOdLNRKW6lKfGvWVp8OurTk7cCMWLx53xBMUc2ea3r1anLPeiE18_kLCWIfyx7LG_dklLmt09OQcLK9rJOd3vqpTem-d0sh1tnoqEt77BnH-Bk_iTkW9EDdaPCPjWZmv8jde4UVjudlVngbv0ZI5RNI4xICz5gDYawqzuaod5yxtCTfoITbFnVbUgQ5xHmvIHIA6SeBakOBxowOhX8If1KE_pQVQDqwj2CABdToAeZTUo6UlxLEvEeWHSH065jjpxUO20pNuBiP9AXS_dZ6kJQjaNgiaTrMeyqDNAZpIiwqGEIe-P4dATKxjvy5ZwYdkXMYGXvCXF23ptPMAu04bhBpj3rdBE0IwbrdcqCpVD-mDXGCVrPKkTB_4Kll0FVdtonKR5XXa5qs6KzGVNa_bOqsz-ZAkC10JLnK-4oVI8lWeLNMkLVLZtFlRyGxVr1jGsZfaLI157ZfObxY6hAGrJFuJpFgYWaMJ48AshMUdjFEmRJyffRWTPtTDJrCMGx0ofKchTQarfVncno6x1yHMxmTdb717RbUYvKk6om2I_y7Fmon1RlM31MvG9UysI_9x-bD17m9sornjrQIT6-O1XyvxbwAAAP__STJtUQ">