[LLVMdev] optimization assumes malloc return is non-null
David Vandevoorde
daveed at vandevoorde.com
Thu May 1 13:01:51 PDT 2008
On May 1, 2008, at 3:30 PM, Sandro Magi wrote:
> Sorry, for j
> On Thu, May 1, 2008 at 1:16 PM, David Vandevoorde
> <daveed at vandevoorde.com> wrote:
>>
>> Another valid implementation of malloc is one that actually returns a
>> non-null pointer in this case, and for such an implementation, a
>> valid
>> reduction is "int main() { return 1; }". That reduction is IMO not
>> only valid, but also defensible and maybe desirable. (And LLVM
>> apparently does so.)
>
> But this reduction depends on knowledge of the malloc implementation,
> which no one has confirmed is actually the case here.
Not really, because the implementation doesn't get called. Another
way of thinking about it is as follows: Let __general_malloc be the
"normal implementation of malloc". Then the compiler replaces that
implementation by
inline void *malloc(size_t n) {
if (this_one_special_call_site()) {
static byte buf[n] __attribute((most_aligned));
return (void*)buf;
} else {
return __general_malloc(n);
}
}
> On Wed, Apr 30, 2008 at 10:21 PM, Chris Lattner <sabre at nondot.org>
> wrote:
>> LLVM should not (and does not, afaik) assume the malloc succeeds in
>> general.
>>
>> If LLVM is able to eliminate all users of the malloc assuming the
>> malloc succeeded (as in this case), then it is safe to assume the
>> malloc
>> returned success.
>
> I don't see how this could be true in general, without either
> knowledge of the malloc implementation, which would be fine, or
> presuming knowledge of the target, which would not be fine. If
> "malloc(sizeof(int))" were changed to "malloc(3245677423)", would it
> still be eliminated?
That's a good question. More specifically, does the _language_ allow
the optimization if I ask for so much storage that the address space
could not possibly accommodate an object of the given size "disjoint
from any other object" (words of 7.20.3/1)? My view is that yes this
is allowed, because the words in 7.20.3/1 only require that for an
_object_ associated with that storage, which doesn't exist here
because the address is never used to create a non-opaque pointer.
Here is 7.20.3 for reference:
"The order and contiguity of storage allocated by successive calls to
the calloc, malloc, and realloc functions is unspecified. The pointer
returned if the allocation succeeds is suitably aligned so that it may
be assigned to a pointer to any type of object and then used to access
such an object or an array of such objects in the space allocated
(until the space is explicitly deallocated). The lifetime of an
allocated object extends from the allocation until the deallocation.
Each such allocation shall yield a pointer to an object disjoint from
anyother object. The pointer returned points to the start (lowest byte
address) of the allocated space. If the space cannot be allocated, a
null pointer is returned. If the size of the space requested is zero,
the behavior is implementation-defined: either a null pointer is
returned, or the behavior is as if the size were some nonzero value,
except that the returned pointer shall not be used to access an object."
Admittedly, that argument is weaker than for small bounded allocations
where hypothetical addresses can just be stolen from non-data pages.
Daveed
More information about the llvm-dev
mailing list