Kevin Qin
2015-Mar-31 09:24 UTC
[LLVMdev] why we assume malloc() always returns a non-null pointer in instruction combing?
Hi, When looking into the bug in https://llvm.org/bugs/show_bug.cgi?id=21421, I found a regression test in Transforms/InstCombine/malloc-free-delete.ll against me to directly fix it. The test is, define i1 @foo() { ; CHECK-LABEL: @foo( ; CHECK-NEXT: ret i1 false %m = call i8* @malloc(i32 1) %z = icmp eq i8* %m, null call void @free(i8* %m) ret i1 %z } According to http://www.cplusplus.com/reference/cstdlib/malloc/, malloc may return null if this memory allocation fails. So why we assume malloc() always returns a non-null pointer here? I think we can do such optimization with operator new, because new never returns null. But for all malloc like allocation(malloc, calloc, and new with std::nothrow), we shouldn't do this. That regression test exists for a long time, I'm not sure if there's any special reason. Does anybody know about this? -- Thanks, Kevin Qin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150331/e1d0a4f4/attachment.html>
mats petersson
2015-Mar-31 09:44 UTC
[LLVMdev] why we assume malloc() always returns a non-null pointer in instruction combing?
The optimisation here is that "nothing uses `m`, so we can assume allocation works and remove the malloc + free pair". What is the purpose of allocating 1 (or 100, or 1000000000) bytes, never use it, and then free it immediately? The test-code in the bug report does rely on the constructor being called, and the bug here is probably [as I'm not familiar with the workings of the compiler in enough detail] that it doesn't recognize that the constructor has side-effects. -- Mats On 31 March 2015 at 10:24, Kevin Qin <kevinqindev at gmail.com> wrote:> Hi, > > > When looking into the bug in https://llvm.org/bugs/show_bug.cgi?id=21421, I > found a regression test in Transforms/InstCombine/malloc-free-delete.ll > against me to directly fix it. The test is, > > define i1 @foo() { > ; CHECK-LABEL: @foo( > ; CHECK-NEXT: ret i1 false > %m = call i8* @malloc(i32 1) > %z = icmp eq i8* %m, null > call void @free(i8* %m) > ret i1 %z > } > > According to http://www.cplusplus.com/reference/cstdlib/malloc/, malloc may > return null if this memory allocation fails. So why we assume malloc() > always returns a non-null pointer here? > > I think we can do such optimization with operator new, because new never > returns null. But for all malloc like allocation(malloc, calloc, and new > with std::nothrow), we shouldn't do this. > > That regression test exists for a long time, I'm not sure if there's any > special reason. Does anybody know about this? > > -- > Thanks, > > Kevin Qin > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
mats petersson
2015-Mar-31 09:48 UTC
[LLVMdev] why we assume malloc() always returns a non-null pointer in instruction combing?
> I think we can do such optimization with operator new, because new never returns null.This is incorrect in the case of `new (std::nothrow) ...` - the whole point of `(std::nothrow)` is to tell new that it should return NULL in case of failure, rather than throw an exception (bad_alloc). But the point here is not the actual return value, but the fact that the compiler misses that the constructor has side-effects. -- Mats On 31 March 2015 at 10:44, mats petersson <mats at planetcatfish.com> wrote:> The optimisation here is that "nothing uses `m`, so we can assume > allocation works and remove the malloc + free pair". > > What is the purpose of allocating 1 (or 100, or 1000000000) bytes, > never use it, and then free it immediately? > > The test-code in the bug report does rely on the constructor being > called, and the bug here is probably [as I'm not familiar with the > workings of the compiler in enough detail] that it doesn't recognize > that the constructor has side-effects. > > -- > Mats > > On 31 March 2015 at 10:24, Kevin Qin <kevinqindev at gmail.com> wrote: >> Hi, >> >> >> When looking into the bug in https://llvm.org/bugs/show_bug.cgi?id=21421, I >> found a regression test in Transforms/InstCombine/malloc-free-delete.ll >> against me to directly fix it. The test is, >> >> define i1 @foo() { >> ; CHECK-LABEL: @foo( >> ; CHECK-NEXT: ret i1 false >> %m = call i8* @malloc(i32 1) >> %z = icmp eq i8* %m, null >> call void @free(i8* %m) >> ret i1 %z >> } >> >> According to http://www.cplusplus.com/reference/cstdlib/malloc/, malloc may >> return null if this memory allocation fails. So why we assume malloc() >> always returns a non-null pointer here? >> >> I think we can do such optimization with operator new, because new never >> returns null. But for all malloc like allocation(malloc, calloc, and new >> with std::nothrow), we shouldn't do this. >> >> That regression test exists for a long time, I'm not sure if there's any >> special reason. Does anybody know about this? >> >> -- >> Thanks, >> >> Kevin Qin >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>
Reasonably Related Threads
- [LLVMdev] why we assume malloc() always returns a non-null pointer in instruction combing?
- [LLVMdev] why we assume malloc() always returns a non-null pointer in instruction combing?
- [LLVMdev] why we assume malloc() always returns a non-null pointer in instruction combing?
- clang-tidy : Modify cert-err60-cpp configuration
- [LLVMdev] How to run two loop passes non-interleaved if they are registered one by one?