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.
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.
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.