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

    <tr>
        <th>Summary</th>
        <td>
            Failure to recognise expanded struct copies as memcpy loops
        </td>
    </tr>

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

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

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

<pre>
    Related to #60742
```c
struct Foo {
 short i16;
    int i32;
};
using S = struct Foo;

// Recognised as memcpy
void copyS(S* __restrict dst, const S* __restrict src, unsigned N) {
    while(N--) {
      *dst++ = *src++;
 }
}

// NOT recognised as memcpy
void copyS2(S* __restrict dst, const S* __restrict src, unsigned N) {
    while(N--) {
      dst->i16 = src->i16;
      dst->i32 = src->i32;
      dst++;
      src++;
 }
}
```
https://simd.godbolt.org/z/o477jfYc1
```s
copyS(Foo*, Foo const*, unsigned int):                     # @copyS(Foo*, Foo const*, unsigned int)
        testl   %edx, %edx
        je      .LBB0_1
 movl    %edx, %edx
        shlq    $3, %rdx
        jmp memcpy@PLT                      # TAILCALL
.LBB0_1: # %while.end
        retq

copyS2(Foo*, Foo const*, unsigned int):                    # @copyS2(Foo*, Foo const*, unsigned int)
 testl   %edx, %edx
        je      .LBB1_3
        movl    %edx, %eax
        xorl    %ecx, %ecx
.LBB1_2: # %while.body
        movzwl  (%rsi,%rcx,8), %edx
        movl 4(%rsi,%rcx,8), %r8d
        movw    %dx, (%rdi,%rcx,8)
        movl %r8d, 4(%rdi,%rcx,8)
        incq    %rcx
        cmpl    %ecx, %eax
        jne     .LBB1_2
.LBB1_3:                                # %while.end
        retq
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8VVtvqzgQ_jXDy6iRGRNCHnhI2kVabdRdtX3Zp4jYTuIKMAebXs6vXxkIufWorVY6KAq-zHye75vBk1urd5VSKUyXML0L8tbtTZM-_PWoS1MFGyPf0wdV5E5JdAaBeMxmEQG7A7aAmPU_0c-ta1rhMDMGYbbs19DuTeNQhzHwwxIi6sqh5jSuwexuHLdWVzt8ROB3eIQ8mvb_lAFl-KCE2VXaKom5xVKVon7vDV6MlihM_f4IlDwCLXC9bpR1jRYOpXVAtyhMZR1ebtpG-M226qSReA80PyGEiK97XSig5P7m5moPEWjR4S-Blh0JoEWH6ReOKnjKI_drZvd_P2HzBXb0u-lJ626A_6HDuM9QI4bpWYKPdpzO7E6SPtpdStM9X5PsUIL9dO9cbYEPGlpdysnOyI0p3MQ0O6DsJ1BmotnsefuvCC8gbD8_1IyvOVp4qXxBd1oO81E6XTmgOfAh4osHiCNE7Pt4JyIgOmVd0aFNlXzz5sPozOpZ9e_Jarlk64EZlualwE997b740VtFfLBprvDL-lB_Eftn9fQh4Y7x0-LP1e1iter9D_HwRS8HTbvimqhKnh_QKPfj9CsYa_v_puE0C9_D6-P7vv7hmp9vfpyG_ALizTSjlRitxNtRyHBNV0L6G_rqtJ-vhcdJfCatBrr1gw4z8cR-waELM_rMrUnkldvrEPeBXIcgrxGujxsA6XY8-DM3XYmhWjuTsz1R1h9IeCn0c6VOckWn-vJffcuXBfWVOj7cK4FMuZzzeR6oNIxns-mcRSwJ9mkcKoqFSIgl4XQbxkpu2HY7TZJotknmyTbQKTHijCgJOTGWTKKQqZhHbC430rtAxFSZ62JSFC-lv-ICbW2r0jhk0Two8o0qbNfaiSr1it0mEPlO36Te52bT7ixErNDW2SOK065QaZbrom2Ub_xjJ0L1VueVVPLQmoWptbLH_oSFMbUN2qZIz2_jnXb7djMRpgTK_EnD66ZuzLMSDijr4rNAWRf_fwEAAP__ydlI-Q">