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

    <tr>
        <th>Summary</th>
        <td>
            clang generates incorrect code with bit shifts passed as function parameter
        </td>
    </tr>

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

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

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

<pre>
    Source:

```
#include <stdlib.h>
#include <string.h>

int main()
{
   int bits = 8;
   char* a = (char*)malloc(1 << bits);
   char* b = (char*)malloc(1 << bits);
   memcpy(b, a, 1 << bits);
   return 0;
}
```

Generated assembler code:

```
main: # @main
        .cfi_startproc
# %bb.0:
 pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset %rbp, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register %rbp
        subq    $32, %rsp
        movl    $0, -4(%rbp)
 movl    $8, -8(%rbp)
        movl    -8(%rbp), %ecx
        movl    $1, %eax
                                        # kill: def $cl killed $ecx
        shll    %cl, %eax
        movslq  %eax, %rdi
 callq   malloc@PLT
        movq    %rax, -16(%rbp)
        movl -8(%rbp), %ecx
        movl    $1, %eax
 # kill: def $cl killed $ecx
        shll    %cl, %eax
 movslq  %eax, %rdi
        callq   malloc@PLT
        movq    %rax, -24(%rbp)
        movq    -24(%rbp), %rdi
        movq    -16(%rbp), %rsi
        movl    -8(%rbp), %ecx
        movl    $1, %eax
 # kill: def $cl killed $ecx
        shll %cl, %eax
        movslq  %eax, %rdx
        callq   memcpy@PLT
 xorl    %eax, %eax
        addq    $32, %rsp
        popq %rbp
        .cfi_def_cfa %rsp, 8
        retq
```

The relevant part is:

```
        shll    %cl, %eax
        movslq %eax, %rdi
```

It should zero-extend, not sign-extend as bit shift is unsigned operation. It's also promoting after the shift which can possibly cause overflow, instead it should promote before the shift. In ideal world, one could use `UINTPTR_C()` to force promoting before the cast, but none of the common compilers understand it.

clang version: Ubuntu clang version 15.0.2-1
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVk1v4zYQ_TX0ZRCBor4POuwmTRGgKBZt9hxQ1MhiS5EKSTnZ_vqCtJx4HScGghUMyuI8vhk9DkfDnZNbjdiS4ispbjZ88aOx7eRV2lTNpjP9j_Zvs1iBJPtC6A2hh7Gk62__yDKphVp6BJJdO98r2SUjyX47b7ZSb4_NcZTaw8SlJqwmrFkt1df9HwAI9k56ByS7gZpkrxYxckvYF-DRRFi9ThDWTFwpIwir0-CZZNeRIvCfWd99cv2Ek5h_EFZ3hF0DD8NHcIt-sRroyxypbs6rGsffUaPlHnvgzuHUKbQgTH9hR6KS2RcgLAOS0_h4CCBeiRjkg_Pc-tka8bJPQFjRdQl9YYd5ceMjQDDYbj5D0uPwIAb-YIbBoYe0PINZbSsHu4arU9hkdsFLhLgIuejQ4lY6j_Ys0i3dypdn7EDn5jdO1QqiMao8Zt8-yDUHj0F1BNVnQCeEJ5i9exTP77pPDxh-grl0hT37VyoVNrvHIXAJFWewDw9vnLpRrU4Lod7zOpmdU49wsK3y9XJFCa6CFdbjkdNvf9y_v517grDjH-v2C0T7xWpckGG9PqUGO5dqJ_BT0Dv-X-AnCh-S_i38V-Xo5-T-TOY9vyP5vvQeS_5s7GFHXwneuOF9f7k8zGZ-vFiGjipW_TPKon_8oLDfjwgWFe649jBz60G6j4v6Z47w-dQ9G9CdBzeaRfXwH1pzhc8edR9WauMhNArrFHAXvmvgRjmEoGHRsY3owczhUyWNTuDOE1Y54MoZmK2ZjJd6C3wI9dqPuC5-GqUYQXANs3FOduoHCL44BLNDOyjzFNxL7TzyHuRLfHtChA4HY_GVL4E7DbJHruDJWBWDNxpBxFWBl5T0-92f99_u_3q4XjuNkoI3MBgr8CjSI2rBnQ9M3eJBBzoz7OfNNBkdbrNUaIMOPVrnuQ6xJsfSCsX1FnZonTTxu_y9W7Rf4Kd5SIuEJuwq3fRt1jdZwzfYpmWV1w3Ls2oztmnF86LJRNqkdYk0TcuipKxucsqxyvpqI1tGWUZTVtOqyIoqESzPi6HMh2oomw4pySlOXKpEqd2UGLvdSOcWbEuaFelG8Q6Vi90gYxqfIBoJY6E5tG1Yc9UtW0dyqqTz7pXFS6-w3b_Odu1YHEgtjLUofOxY4En68TVzHMyho4npNCxahLwJ54BP6NFuFqva0fs5ngl2S9jtVvpx6RJhJsJug-f1djVb8w8KT9htjNcRdhvf5_8AAAD__432-QY">