[llvm-dev] Potential issue with noalias @malloc and @realloc (original) (raw)
Flamedoge via llvm-dev llvm-dev at lists.llvm.org
Tue Apr 11 16:14:13 PDT 2017
- Previous message: [llvm-dev] Potential issue with noalias @malloc and @realloc
- Next message: [llvm-dev] Potential issue with noalias @malloc and @realloc
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
I think you are spot-on!
From http://en.cppreference.com/w/c/memory/malloc, A previous call to free <http://en.cppreference.com/w/c/memory/free> or realloc <http://en.cppreference.com/w/c/memory/realloc> that deallocates a region of memory synchronizes-with a call to mallocthat allocates the same or a part of the same region of memory. This synchronization occurs after any access to the memory by the deallocating function and before any access to the memory by malloc. There is a single total order of all allocation and deallocation functions operating on each particular region of memory.
So only "non-freed" malloc pointers are No-Alias which makes it flow-sensitive. There is no reason why malloc couldn't return previously freed location.
Regards, Kevin
On Tue, Apr 11, 2017 at 3:32 PM, Sanjoy Das via llvm-dev < llvm-dev at lists.llvm.org> wrote:
Hi all,
I think I've spotted a semantic issue with marking @malloc and @realloc as noalias. Say we have the program: int f() { int* p0 = malloc(size of(int)); free(p0); int* p1 = malloc(sizeof(int)); if (!p1) return 20; int value = 0; for (int i = 0; i < 1; i++) { *p1 = 20; value = *p1; if (false) // "false" is obscured in a way the compiler can't fathom if (p0 == p1) a(); else b(); } return result; } The program above is well defined, and will always return 20. However, if we first unswitch loops: int f() { int* p0 = malloc(size of(int)); free(p0); int* p1 = malloc(sizeof(int)); if (!p1) return 20; int value = 0; if (p0 == p1) { for (int i = 0; i < 1; i++) { *p1 = 20; value = *p1; if (false) a(); } } else { // Other copy of the loop that calls b() in dead code } return result; } and then run GVN::propgateEquality that replaces one use of p1 with p0 but not the other (for some reason, say the other use was obscured behind a function call): int f() { int* p0 = malloc(size of(int)); free(p0); int* p1 = malloc(sizeof(int)); if (!p1) return 20; int value = 0; if (p0 == p1) { for (int i = 0; i < 1; i++) { *p0 = 20; // S0 value = *p1; // L0 if (false) a(); } } else { // Other copy of the loop that calls b() in dead code } return result; }
Now we have a problem -- since p0 NoAlias p1 (distinct @malloc() calls), we can reorder S0 and L0 (or LICM L0): int f() { int* p0 = malloc(size of(int)); free(p0); int* p1 = malloc(sizeof(int)); if (!p1) return 20; int value = 0; if (p0 == p1) { for (int i = 0; i < 1; i++) { value = *p1; // L0 *p0 = 20; // S0 if (false) a(); } } else { // Other copy of the loop that calls b() in dead code } return result; } and we'll now return garbage if p0 == p1 (likely) and p1 is not null (also likely). I do not yet have a solution for this. Let me know what you think! Thanks, -- Sanjoy
LLVM Developers mailing list llvm-dev at lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170411/dfa41a4d/attachment.html>
- Previous message: [llvm-dev] Potential issue with noalias @malloc and @realloc
- Next message: [llvm-dev] Potential issue with noalias @malloc and @realloc
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]