LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 38583 - Clarify assumptions of llvm.memcpy/memmove/memset.* when count is 0
Summary: Clarify assumptions of llvm.memcpy/memmove/memset.* when count is 0
Status: RESOLVED FIXED
Alias: None
Product: Documentation
Classification: Unclassified
Component: General docs (show other bugs)
Version: trunk
Hardware: PC Linux
: P enhancement
Assignee: Unassigned LLVM Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-08-15 12:20 PDT by Ralf Jung
Modified: 2019-02-26 10:57 PST (History)
5 users (show)

See Also:
Fixed By Commit(s): rL354911 76eb4b02d93b3a7704b496f3e16dd14bf72cb3a9


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ralf Jung 2018-08-15 12:20:58 PDT
Last year, I asked on the mailing list [0] to clarify which are the assumptions that LLVM makes when llvm.memcpy/memmove/memset.* (the intrinsics, not the C functions) are called with a count of 0 -- including the case where the count is not statically known, but happens to be 0 at run-time.  The concept of a "dangling" pointer does not make much sense for size 0 (by definition, all the bytes it points to are allocated because it points to no bytes).  However, some questions remain open.  Specifically:

- Is it okay for some of the pointers to be NULL?
- Is it okay for some of the pointers to not be aligned, even though the annotation says they should be aligned?

Having definite answers to such questions is important for us in Rust, so that we can settle in rules for our intrinsics that compile to LLVM's. I hope the "Documentation" product is the right one for such issues.

[0] https://lists.llvm.org/pipermail/llvm-dev/2017-July/115665.html
Comment 1 Eli Friedman 2018-08-16 16:38:02 PDT
The answer probably should be that a null/invalid pointer is okay, but violating the align attribute is not.

Justification: if the size is zero, the intrinsics don't perform any memory operations, so the pointer doesn't have to point to anything in particular.  And "align" is a generic parameter attribute which should have the same meaning everywhere.  (If there's a significant optimization justification, we could possibly define the "align" attribute to produce poison or something like that, but UB is more straightforward to reason about.)

https://llvm.org/docs/LangRef.html#parameter-attributes should probably be fixed to explicitly say "if the pointer is not aligned, the behavior is undefined", like it does for other attributes like nonnull. And put a note on memcpy/memset/memmove noting that if the size is zero, the pointer doesn't have to point to valid memory.  And maybe explicitly note that the rules for the "align" attribute are the same for memcpy/memset/memmove as they are for other calls.

If you're interested, you can try writing a patch for LangRef yourself (it's docs/LangRef.rst in the LLVM repository).  Or I'll probably get to it at some point otherwise.
Comment 2 Ralf Jung 2018-08-17 10:35:56 PDT
Thanks!

I am wondering, why do you treat the non-nullness separate from alignedness?  I understand the reasoning for why the pointer must be aligned even for no access, but I think the same reasoning applied to being NULL.
Comment 3 Eli Friedman 2018-08-20 13:07:13 PDT
The "align" attribute is generic; it needs to have the same meaning in all contexts. And the simplest useful way to define for other contexts is "the bottom N bits are zero, or the behavior is undefined".

If the arguments to memcpy were marked "nonnull", it would similarly be UB to pass a null pointer.  But they aren't, generally, so there isn't any particular reason to treat null specially.
Comment 4 Ralf Jung 2018-08-28 13:37:06 PDT
I see, this makes sense.

In Rust, I usually like to treat "aligned and non-NULL" together; this would be the first and only case where the two requirements go separate.  So to be safe we should likely just require both.
Comment 5 Ralf Jung 2019-02-01 10:09:18 PST
I submitted a patch at https://reviews.llvm.org/D57600.  That's quite a bit more complicated than one is used to nowadays, so I hope I didn't make a mistake.
Comment 6 Kristina Brooks 2019-02-26 10:57:08 PST
Landed the documentation updates as r354911 (GitHub monorepo commit 76eb4b02d93b3a7704b496f3e16dd14bf72cb3a9).