[LLVMdev] optimization assumes malloc return is non-null

David Vandevoorde daveed at vandevoorde.com
Wed Apr 30 17:57:07 PDT 2008


On Apr 30, 2008, at 7:17 PM, David A. Greene wrote:
> On Wednesday 30 April 2008 17:26, David Vandevoorde wrote:
>
>>>> ...malloc() is not specified to access a volatile
>>>> object, modify an object, or modifying a file (directly or
>>>> indirectly); i.e., it has no side effect from the language point of
>>>> view.
>>>
>>> Daveed:
>>>
>>> Good to know that I was looking at the correct section. I do not  
>>> agree
>>> that your interpretation follows the as-if rule, because I do not
>>> agree
>>> with your interpretation of the C library specification of malloc().
>>
>> Before I go on, let me state that this is not a contentious issue
>> among WG14: There is no doubt that the intent of the standard is that
>> this be a valid optimization.
>
> Maybe I missed something, but aren't we all talking about the wrong  
> thing
> here?  It seems to me that this isn't about side effects, it's about  
> the
> return value of malloc.  Why can LLVM assume malloc will always return
> non-zero?

It cannot assume that in the general case.  It can do so here because  
the return value is not used further on.  The side effects issue comes  
about because the compiler needs to know that the call to malloc was  
not observable other than through the return value.  To re-quote a  
part of 5.1.2.3/3: "An actual implementation need not evaluate part of  
an expression if it can deduce that its value is not used and that no  
needed side effects are produced".  So there are two conditions to  
optimize this: Track the return value to make sure nothing interesting  
(i.e., unknown) happens to it, and be sure that there are no  
observable side effects from the call itself (in this case, take  
advantage of the fact that "malloc" is part of the language  
implementation).

Note that more interesting optimizations are possible.  E.g., it's  
perfectly valid to transform:

	void f(size_t n) {
	  char *str = (char*)malloc(n);
	  // use str[0 .. 99 ]
	  free(str);
	}

into

	void f(size_t n) {
	  char *str = (char*)alloca(n);
	  // use str[0 .. 99 ]
	}

(Can LLVM do that?  Is that maybe why the optimization happens?)

	Daveed




More information about the llvm-dev mailing list