[LLVMdev] why we assume malloc() always returns a non-null pointer in instruction combing?

David Majnemer david.majnemer at gmail.com
Wed Apr 1 00:57:59 PDT 2015


On Wed, Apr 1, 2015 at 12:15 AM, Kevin Qin <kevinqindev at gmail.com> wrote:

> Hi David and Mats,
>
> Thanks for your explanation. If my understanding is correct, it means we
> don't need to consider the side-effect of malloc/free unless compiling with
> -ffreestanding. Because without -ffreestanding, user defined malloc/free
> should be compatible with std library. It makes sense to me.
>
> My point is, in std library, malloc is allowed to return null if this
> malloc failed. Why compiler knows it must succeed at compile time?  I
> slightly modified the regression case,
>
> define i1 @CanWeMallocWithSize(i32 a) {
> ; CHECK-LABEL: @foo(
> ; CHECK-NEXT: ret i1 false
>   %m = call i8* @malloc(i32 a)
>   %z = icmp eq i8* %m, null
>   call void @free(i8* %m)
>   ret i1 %z
> }
>
> It's possible that this function is used to detect whether the runtime
> environment can malloc a block of memory with size a. Besides, this
> function can help to apply a large block of memory from system to memory
> allocator and reduce the system call from a lot of malloc with small size
> next. At some extreme situations, it may fail to pass this check, then
> program can show a decent error message and stop. So the problem is, it's
> not simply malloc a size of memory and then directly free it, but the
> pointer from malloc is used to compare with null and finally affect the
> return value. So this optimization may change the original semantic.
>

A program cannot rely on prior call to a pair of malloc and free to suggest
that a subsequent call to malloc might succeed.  In fact, a valid
implementation of a debug malloc might unconditionally report that the nth
call to malloc will fail in order to help find bugs in a program.


>
>
> Thanks,
> Kevin
>
> 2015-04-01 12:52 GMT+08:00 David Majnemer <david.majnemer at gmail.com>:
>
>>
>>
>> On Tue, Mar 31, 2015 at 7:59 PM, Jiangning Liu <liujiangning1 at gmail.com>
>> wrote:
>>
>>> Hi Mats,
>>>
>>> I think Kevin's point is malloc can return 0, if malloc/free pair is
>>> optimized way, the semantic of the original would be changed.
>>>
>>> On the other hand, malloc/free are special functions, but programmers
>>> can still define their own versions by not linking std library, so we must
>>> assume malloc/free always have side-effect like other common functions,
>>> unless we know we will link std library only at link-time.
>>>
>>
>> If programmers want to do this, they need to compile their program with
>> -ffreestanding.
>>
>>
>>>
>>> Thanks,
>>> -Jiangning
>>>
>>>
>>> 2015-03-31 17:51 GMT+08:00 Kevin Qin <kevinqindev at gmail.com>:
>>>
>>>> Yes, I classified `new (std::nothrow)` to be a malloc like allocation.
>>>> See the next sentence.
>>>>
>>>>
>>>> 2015-03-31 17:48 GMT+08:00 mats petersson <mats at planetcatfish.com>:
>>>>
>>>>> > 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
>>>>> >>
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Best Regards,
>>>>
>>>> Kevin Qin
>>>>
>>>> _______________________________________________
>>>> LLVM Developers mailing list
>>>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>>>
>>>>
>>>
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>>
>>>
>>
>
>
> --
> Best Regards,
>
> Kevin Qin
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150401/6a128b92/attachment.html>


More information about the llvm-dev mailing list