<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/61791>61791</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Incorrect folding of two __builtin_memcpy_inline into memmove
</td>
</tr>
<tr>
<th>Labels</th>
<td>
llvm:optimizations
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
miyuki
</td>
</tr>
</table>
<pre>
Consider the following code implementing a 16-byte memmove:
```
void test(void *src, void *dest) {
char temp[16];
__builtin_memcpy_inline(temp, src, 16);
__builtin_memcpy_inline(dest, temp, 16);
}
```
The point of memcpy_inline builtin is to avoid calls to library functions so that the builtin can be used to implement library functions such as memcpy and memmove. When targeting Arm M-profile Clang compiles this code into a call to `__aeabi_memmove`:
```
$clang -target arm-arm-none-eabi -mcpu=cortex-m7 -O2 -S test.c
```
produces
```
test:
push {r7, lr}
mov r7, sp
mov r3, r0
movs r2, #16
mov r0, r1
mov r1, r3
bl __aeabi_memmove
pop {r7, pc}
```
The folding happens at LLVM IR level, in MemCpyOptPass:
```
*** IR Dump After ADCEPass on test ***
; Function Attrs: nounwind
define dso_local void @test(ptr noundef %0, ptr noundef %1) local_unnamed_addr #0 {
%3 = alloca [16 x i8], align 1
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %3)
call void @llvm.memcpy.inline.p0.p0.i64(ptr nonnull align 1 %3, ptr align 1 %0, i64 16, i1 false)
call void @llvm.memcpy.inline.p0.p0.i64(ptr align 1 %1, ptr nonnull align 1 %3, i64 16, i1 false)
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %3)
ret void
}
*** IR Dump After MemCpyOptPass on test ***
; Function Attrs: nounwind
define dso_local void @test(ptr noundef %0, ptr noundef %1) local_unnamed_addr #0 {
%3 = alloca [16 x i8], align 1
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %3)
call void @llvm.memcpy.inline.p0.p0.i64(ptr nonnull align 1 %3, ptr align 1 %0, i64 16, i1 false)
call void @llvm.memmove.p0.p0.i64(ptr align 1 %1, ptr align 1 %0, i64 16, i1 false)
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %3)
ret void
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsVk1v4zYQ_TX0ZWBDomTFPujg2DWwwC62aIv2aFDkyGLLL5BUdt1fX5CSvUkQF2n3VKCBAlkcvjcfbzQiC0GeDWJL1o9kfViwMQ7Wt1pexj_korPi0u6tCVKghzgg9FYp-0WaM3ArEKR2CjWamFYYlM2yu0QEjVrbJyTVjhQHUuxIU8xXfnyyUkDEEAnd5N-E7oLnhO7h-iiydQvk4XHCAPCBeYioHVk_lg1ZH0h1s51O3ShVlOakUXN3OUmjpEFCNxlA9zDzlw2h23cBpwj2cCV4iSQPhzdT-2VAcFaaCLaHF5QwOwIZIFpgOVPOlMqPSnae-Qv0o-FRWhMgWIgDi7nqVyhnBjqEMaBIoFv134KPfAAW5hiAGXFVZQW_DWggMn_GrNvOa_i0dN72UiHsFcvqaicVBoiDDLPWJoWdQ07OSVOcTgxZJ09XuZvim-JvFYfQmmf25eQcmNfL9G-swWWigqXmbiTVgVsf8etSP8DyM4Xlz7ldVvxNWuetGDmGN425za5RgRvDAACprfxDUlX5m5Iw_2n7lO_ThuDuWKtk9bOXtBzyMk3LhFZlcwdXZFx5x1pmazVbOzWZXxf6BdZZBy9ycvzvurO3SiTVB-YcmgAswsePv36CDz-BwidUiUEa-IR67y6fXfyRhXDvRSZ0vhL6MGoHuz6ih91h_0PCgTVZOLhtnHHVIxznVoVdjD55AGNH80UaMe0R2Ke3RgR7UpYzNY-GupgHh4s-IwT2QOg6l_XVWpkmSAafRmOYRnFiQvgkT_F8shC6roBUB2Aq7YY8YOAryE2aMnQPTMmzgZtm-RW4hqPUk14p2WOUGlchMh9XriB0I5s6D41rWMaMSmVfaZDcpZpe2NU0NFauSJds6lvGE80c0Uw3uXi2lqvxLQBZQs9UwO9w_Iy8fJ3T62D-oeNb8dCI95fOY8w0r-fxnZZ80c__9-V_qy_zZ-s9Hfmdrv5dJ95txeuwXIi2EttqyxbYls2mKLb1tioXQ9v0nUBOm4ZVvOebsqmLLeflpujrbls364VsaUGroqLbsipoWa5qgc26Kvq66Kum4DWpC9RMqlWO3_rzQoYwYtuUD9tyoViHKuSzHaVpB6l21kWp5Z8sHxMIpenU59tkXHbjOaRSyBDDN8Ioo8L2g-HWe-Tx9gGxPcQv9t4JajouzNotRq_aIUaXvyT0SOjxLOMwdituNaHHHNp0S-eQ35FHQo85k0DoMSfzVwAAAP__lHkx0w">