Guillaume Chatelet via llvm-dev
2019-Jun-05 13:36 UTC
[llvm-dev] @llvm.memcpy not honoring volatile?
The following IR with the volatile parameter set to true> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %0, i8* align 1 %1, i647, i1 true) generates the following asm:> movl (%rsi), %eax > movl 3(%rsi), %ecx > movl %ecx, 3(%rdi) > movl %eax, (%rdi)It performs an overlapping read/write which - I believe - is violating the volatile semantic Full example here: https://godbolt.org/z/P_rjBT Is this a bug or am I misunderstanding volatile in this context? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190605/cd914fa6/attachment-0001.html>
Eli Friedman via llvm-dev
2019-Jun-05 20:49 UTC
[llvm-dev] @llvm.memcpy not honoring volatile?
In general, the LangRef specification of “volatile” doesn’t specify how any particular memory access will be lowered. This includes the number of memory accesses, the number of bytes accessed, and whether the accesses overlap. That’s because it’s different for every target, depending on the available instructions. The only universal guarantee is that volatile operations are emitted in source order relative to other volatile operations. (See http://llvm.org/docs/LangRef.html#volatile-memory-accesses .) For all in-tree targets, where possible, loads and stores with an appropriate scalar type and alignment will lowered to a single instruction. Whether this applies to any particular combination of type/alignment depends on the subtarget. For memcpy, or for loads and stores which can’t be lowered to a single instruction, we don’t promise to generate any particular sequence. I don’t see any particular reason to guarantee that a volatile memcpy will access each byte exactly once. How is that useful? -Eli From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of Guillaume Chatelet via llvm-dev Sent: Wednesday, June 5, 2019 6:36 AM To: llvm-dev at lists.llvm.org Subject: [EXT] [llvm-dev] @llvm.memcpy not honoring volatile? The following IR with the volatile parameter set to true> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %0, i8* align 1 %1, i64 7, i1 true)generates the following asm:> movl (%rsi), %eax > movl 3(%rsi), %ecx > movl %ecx, 3(%rdi) > movl %eax, (%rdi)It performs an overlapping read/write which - I believe - is violating the volatile semantic Full example here: https://godbolt.org/z/P_rjBT Is this a bug or am I misunderstanding volatile in this context? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190605/dbdbd8ec/attachment.html>
Tim Northover via llvm-dev
2019-Jun-05 21:28 UTC
[llvm-dev] @llvm.memcpy not honoring volatile?
On Wed, 5 Jun 2019 at 13:49, Eli Friedman via llvm-dev <llvm-dev at lists.llvm.org> wrote:> I don’t see any particular reason to guarantee that a volatile memcpy will access each byte exactly once. How is that useful?I agree it's probably not that useful, but I think the non-duplicating property of volatile is ingrained strongly enough that viewing a memcpy as a single load and store to each unit (in an unspecified order) should be legitimate; so I think this actually is a bug. As the documentation says though, it's unwise to depend on the behaviour of a volatile memcpy. Cheers. Tim.