Malloc null checks, why sometimes are moved, and sometimes not?


2018-04-14 7:51 GMT+08:00 Krzysztof Parzyszek via llvm-dev
:


Here is simple test code:

LLVM generally assumes that malloc never fails.

But I dont understand difference between these two example functions - and
why null check was not removed in f1, since in f2 it was removed.

That's because the return value from malloc is discarded in f2. In that case
it simply doesn't matter if the malloc happened or not, and can be assumed
to have succeeded.

Wouldn't such assumption be too aggressive?

Normally, yes, but the standard explicitly allows the compiler to not 
call allocation/deallocation functions if the storage can be provided in 
another way. If the storage that would have been allocated by malloc 
cannot ever be accessed, we can pretend that it has been successfully 
provided in some way.

-Krzysztof

How often does that really occur in normal programs? Why bother? I find it quite surprising to fold away the call. While the pointer doesn’t escape F2(), the code does test the existance of the memory with the “if (!ptr)”. That would be enough to retain the call on all the compilers I’ve ever worked on.

John

The point is not to fold the check, the point is to promote heap
allocations to stack allocations when possible. Consider rewriting this:
   int *pz = new int(0);
   // use *p, do not escape p.
   delete p;
into:
   int z = 0;
   // use z in place of *p, do not escape &z.

The null check folds away as a consequence, not by design.

2018-04-14 7:51 GMT+08:00 Krzysztof Parzyszek via llvm-dev
<llvm-dev@lists.llvm.org>:

Here is simple test code:
https://godbolt.org/g/mjAUpu

LLVM generally assumes that malloc never fails.

But I dont understand difference between these two example functions - and
why null check was not removed in f1, since in f2 it was removed.

That's because the return value from malloc is discarded in f2. In that

case

it simply doesn't matter if the malloc happened or not, and can be assumed
to have succeeded.

Wouldn't such assumption be too aggressive?

Normally, yes, but the standard explicitly allows the compiler to not
call allocation/deallocation functions if the storage can be provided in
another way. If the storage that would have been allocated by malloc
cannot ever be accessed, we can pretend that it has been successfully
provided in some way.

-Krzysztof

How often does that really occur in normal programs? Why bother? I find

it quite surprising to fold away the call. While the pointer doesn't
escape F2(), the code does test the existance of the memory with the "if
(!ptr)". That would be enough to retain the call on all the compilers I've
ever worked on.