<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/120453>120453</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Insufficient Optimization of memcpy-Like Loop with Non-Null Pointers
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
jonathan-gruber-jg
</td>
</tr>
</table>
<pre>
Given a `memcpy`-like loop whose pointer operands are known to be non-null, Clang does not optimize the loop into just an unconditional branch to `memcpy`.
Minimal test case:
```
#include <stddef.h>
void my_void_memcpy(void *restrict dst, const void *restrict src, size_t n) {
if (!src || !dst) {
unreachable();
}
/* At this point, we know that src and dst are both non-null. */
for (size_t i = 0; i < n; ++i) {
*((char *)dst + i) = *((char *)src + i);
}
}
```
I only tested the target architectures x86_64, aarch64, and riscv64, but I would not be surprised if other targets have the same problem.
Host system: Arch Linux, x86_64.
Clang version: official Arch Linux package of clang, version 18.1.8-4.
Command line to reproduce results: clang -c test.c -O\<opt-level\>.
x86_64 assembly (Intel syntax), with -Os, -O2, or -O3:
```
my_void_memcpy:
test rdx, rdx
jne memcpy
ret
```
aarch64 assembly, with -Os, -O2, or -O3:
```
my_void_memcpy:
cbz x2, .LBB0_2
b memcpy
.LBB0_2:
ret
```
riscv64 assembly, with -Os, -O2, or -O3:
```
my_void_memcpy:
beqz a2, .LBB0_2
tail memcpy
.LBB0_2:
ret
```
Each of the tested targets check if `n` is `0` and, if so, execute a return instruction; otherwise, they branch to `memcpy`. However, `memcpy` already checks if `n` is `0`, so, because both `src` and `dst` are non-null, `my_void_memcpy` could be further optimized into just an unconditional branch to `memcpy`.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJysVt1y4ygTfRp80yUXRv7ThS9sZ_JNqvJN9g1SCLUtEgReaNnxPP1WI2XWM8le7NZUuSygm9MHON2gU7JHj7gRi51Y3E10T22Im5fgNbXaF8fY1xiLl-OkDs118z97Rg8axFJ22JnTVSxl4ewrggvhBJc2JIRTsJ4wQjhh1L5JoCPCqw8XDxSgRvDBF753Tqg97J32R2gCJvCBIJzIdvY7ArUjpvUU4KVPBNpD703wjSUbvHZQR-1Ny6C3fKZCboXc_t9622kHhInA6ISi5GGxlONPboUqrTeubxBEuU_UNHiYtqL8MiCcg22guz7z93mEV-s8KtQ2YqJoDUGTiBdigk8EH6wpGrYm-x2fCbxQFYjVLgeo7AGEWgs1S9GAWO3Fag9CzTLgjZuQVe8jatPq2mGeUYny3bi6G9hyW90LtYUtAbU2DefAwS_D9gO1OhMC7RumnQ-mDtT-OJEpc2eYd8hDiMxxpG9BlHcgRbnLzT14bgq1E2pnf-WckdZCrU2r44BbcVChdjA4l3fwmVPejdHp13UO_7dnKLcPELy75oPGJguHdDwiL8-0ltBQHzHB23r5vJzzfmg2jE3fQLTJnIdu3RM8wCX0rslyrBFSH0_RJmzAHiBQi3GET9Dq8yDUpDuEUwy1w26U39eQCNI1EXai3MI2mhYere_fOMxAZfQcMuCMMdng2TccDtZY7W4mwUmbV31ECAcw7M8o4xSYraez6br4gRe6jpflrEfOjYinGJreIERMvaPEMTIIFCbv2tRA8SQWe1Huw4kKh2d0uftlhBz4gk4Ju9pdWREPntBBunrSb3xOLDNLLRRPidvFk-JPiFA8lR8z75esKke1MRkhq9jkXeJPHn7xKGQ1-uaRiPRRB-Ox_qD5eziZ-ruQ1VueOn3c7eSzGgz1Lad3y_usTwmOQvvNBGv8kxnqjwxJW_evSX7RpmWZ5TwaU2rUu2nRvHIaiKX0YinBJm7yXE4kjm8PkAI38A1NTwgaIlIfPVifKPaGssh3QyZdbEJ2phav_1TN4Wu44Bkj-90aQLuIurkOrNLntHLpzXxqNLpPY7kTS8l1eaDNPS653Is_X04c7-dNX0owuTrUCIc-5nLwfmc1_-GumjSbsqnKSk9wM1uV88Vczstq0m50s16jWhykqub1fFHOZ9WiQaUaibJqFmpiN0qq-UzN1rPlfDVbT1eVkSt9KPUMy4Oq1mIusdPWTZ07d9MQjxObUo-bmZLzRTlxukaX8r2vlMcLZKtQip8BccOTiro_JjGXziZKf8OQJYebB5_6XKjQEzwNW6B5sSyeYYHFI78MHvPLgGX-LfjiW-8c_DG8ENKkj27TEp24JuXb6_5oqe3rqQmdUPcccvwUpxhe0JBQ95loEup-XMl5o_4KAAD__88nr1M">