<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">There was some previous discussion on
this optimization back in 2008:<br>
<br>
<a class="moz-txt-link-freetext" href="https://groups.google.com/forum/#!topic/llvm-dev/lV30rcmF0ss">https://groups.google.com/forum/#!topic/llvm-dev/lV30rcmF0ss</a><br>
<br>
I found <span class="_username"><span style="color: rgb(34, 34,
34);" class="G3J0AAD-E-a">John Regehr's explaination helpful:<br>
<br>
"</span></span><span class="_username"><span style="color:
rgb(34, 34, 34);" class="G3J0AAD-E-a">To say that LLVM
*assumes* that malloc() succeeds or fails is misleading. This
misstatement may be the root of people's ongoing problems in
understanding this transformation and its validity.</span></span>
<p>The right way to think about it is: LLVM is supplying an
alternate implementation of malloc that happens to run at
compile time, and happens <br>
to succeed all the time. This implementation is -- as I
understand the C standard -- a perfectly legal one. It has
nothing to do with the version of malloc() found in libc except
that the two implementations share a common API."</p>
<span class="_username"><span style="color: rgb(34, 34, 34);"
class="G3J0AAD-E-a"></span></span><br>
On 01/04/15 09:27, James Molloy wrote:<br>
</div>
<blockquote
cite="mid:CALCTSA3cYKUGLvkYN9Ua=ohd9MahiionuXtP1JsA2O=0bt3UVQ@mail.gmail.com"
type="cite">
<meta http-equiv="Content-Type" content="text/html;
charset=windows-1252">
<div dir="ltr">Hi Jiangning,<br>
<br>
<div>Sorry, I don't buy that argument. I don't see why the
compiler statically emulating the behaviour of a well behaved
malloc/free pair is any different to it inlining a version of
strcmp() (the library may have a strcmp that just returns -1 -
the standard says it's allowed to), or doing constant
propagation with well known library calls such as fabs().</div>
<div><br>
</div>
<div>The non -ffreestanding behaviour is that the compiler
*knows* it is sitting on top of a C library and it knows
vaguely what a C library behaves like. Granted, malloc() is
one of the few C library functions that the compiler can do
something with that can have sideeffects, but removing it
completely is certainly a good thing.</div>
<div><br>
</div>
<div>Consider:</div>
<div><br>
</div>
<div>int *my_useless_buffer = malloc(LOTS);</div>
<div>for (n : X) {</div>
<div> my_useless_buffer[0] += n;</div>
<div>}</div>
<div>free(my_useless_buffer);</div>
<div><br>
</div>
<div>The compiler would be expected to reduce my_useless_buffer
to a single int and remove the malloc. I agree with David that
-ffreestanding is the way to inform the compiler that it
shouldn't make any assumptions about
malloc/free/strcmp/memcpy/memset...</div>
<div><br>
</div>
<div>Cheers,</div>
<div><br>
</div>
<div>James</div>
</div>
<br>
<div class="gmail_quote">On Wed, 1 Apr 2015 at 09:20 David
Majnemer <<a moz-do-not-send="true"
href="mailto:david.majnemer@gmail.com">david.majnemer@gmail.com</a>>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">On Wed, Apr 1, 2015 at 12:15 AM,
Kevin Qin <span dir="ltr"><<a moz-do-not-send="true"
href="mailto:kevinqindev@gmail.com" target="_blank">kevinqindev@gmail.com</a>></span>
wrote:<br>
</div>
</div>
</div>
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">
<div>Hi David and Mats,</div>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>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,</div>
<div><br>
</div>
<div>define i1 @CanWeMallocWithSize(i32 a) {</div>
<span>
<div>; CHECK-LABEL: @foo(</div>
<div>; CHECK-NEXT: ret i1 false</div>
<div> %m = call i8* @malloc(i32 a)</div>
<div> %z = icmp eq i8* %m, null</div>
<div> call void @free(i8* %m)</div>
<div> ret i1 %z</div>
<div>}</div>
<div><br>
</div>
</span>
<div>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. </div>
</div>
</blockquote>
<div><br>
</div>
</div>
</div>
</div>
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<div>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.</div>
<div> </div>
</div>
</div>
</div>
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">
<div><br>
</div>
<div><br>
</div>
<div>Thanks,</div>
<div>Kevin</div>
</div>
</blockquote>
</div>
</div>
</div>
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>
<div>
<div class="gmail_extra"><br>
<div class="gmail_quote">2015-04-01 12:52
GMT+08:00 David Majnemer <span dir="ltr"><<a
moz-do-not-send="true"
href="mailto:david.majnemer@gmail.com"
target="_blank">david.majnemer@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote"
style="margin:0 0 0 .8ex;border-left:1px
#ccc solid;padding-left:1ex">
<div dir="ltr"><br>
<div class="gmail_extra"><br>
<div class="gmail_quote"><span>On Tue,
Mar 31, 2015 at 7:59 PM, Jiangning
Liu <span dir="ltr"><<a
moz-do-not-send="true"
href="mailto:liujiangning1@gmail.com"
target="_blank">liujiangning1@gmail.com</a>></span>
wrote:<br>
<blockquote class="gmail_quote"
style="margin:0 0 0
.8ex;border-left:1px #ccc
solid;padding-left:1ex">
<div dir="ltr">Hi <span
style="font-size:14px">Mats</span>,
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>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.</div>
</div>
</blockquote>
<div><br>
</div>
</span>
<div>If programmers want to do this,
they need to compile their program
with -ffreestanding.</div>
<div>
<div>
<div> </div>
<blockquote class="gmail_quote"
style="margin:0 0 0
.8ex;border-left:1px #ccc
solid;padding-left:1ex">
<div dir="ltr">
<div><br>
</div>
<div>Thanks,</div>
<div>-Jiangning</div>
<div><br>
</div>
</div>
<div>
<div>
<div class="gmail_extra"><br>
<div class="gmail_quote">2015-03-31
17:51 GMT+08:00 Kevin
Qin <span dir="ltr"><<a
moz-do-not-send="true" href="mailto:kevinqindev@gmail.com"
target="_blank">kevinqindev@gmail.com</a>></span>:<br>
<blockquote
class="gmail_quote"
style="margin:0 0 0
.8ex;border-left:1px
#ccc
solid;padding-left:1ex">
<div dir="ltr">Yes, I
classified `new
(std::nothrow)` to
be a malloc like
allocation. See the
next sentence.<br>
<div><span
style="font-size:14px"><br>
</span>
<div
class="gmail_extra">
<div>
<div><br>
<div
class="gmail_quote">2015-03-31
17:48
GMT+08:00 mats
petersson <span
dir="ltr"><<a
moz-do-not-send="true" href="mailto:mats@planetcatfish.com"
target="_blank">mats@planetcatfish.com</a>></span>:<br>
<blockquote
class="gmail_quote"
style="margin:0px
0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span>>
I think we can
do such
optimization
with operator
new, because
new never
returns null.<br>
<br>
</span>This is
incorrect in
the case of
`new
(std::nothrow)
...` - the
whole<br>
point of
`(std::nothrow)`
is to tell new
that it should
return NULL in<br>
case of
failure,
rather than
throw an
exception
(bad_alloc).<br>
<br>
But the point
here is not
the actual
return value,
but the fact
that<br>
the compiler
misses that
the
constructor
has
side-effects.<br>
<br>
--<br>
Mats<br>
<div>
<div><br>
<br>
<br>
On 31 March
2015 at 10:44,
mats petersson
<<a
moz-do-not-send="true"
href="mailto:mats@planetcatfish.com" target="_blank">mats@planetcatfish.com</a>>
wrote:<br>
> The
optimisation
here is that
"nothing uses
`m`, so we can
assume<br>
>
allocation
works and
remove the
malloc + free
pair".<br>
><br>
> What is
the purpose of
allocating 1
(or 100, or
1000000000)
bytes,<br>
> never use
it, and then
free it
immediately?<br>
><br>
> The
test-code in
the bug report
does rely on
the
constructor
being<br>
> called,
and the bug
here is
probably [as
I'm not
familiar with
the<br>
> workings
of the
compiler in
enough detail]
that it
doesn't
recognize<br>
> that the
constructor
has
side-effects.<br>
><br>
> --<br>
> Mats<br>
><br>
> On 31
March 2015 at
10:24, Kevin
Qin <<a
moz-do-not-send="true"
href="mailto:kevinqindev@gmail.com" target="_blank">kevinqindev@gmail.com</a>>
wrote:<br>
>> Hi,<br>
>><br>
>><br>
>> When
looking into
the bug in <a
moz-do-not-send="true"
href="https://llvm.org/bugs/show_bug.cgi?id=21421"
target="_blank">https://llvm.org/bugs/show_bug.cgi?id=21421</a>, I<br>
>> found
a regression
test in
Transforms/InstCombine/malloc-free-delete.ll<br>
>>
against me to
directly fix
it. The test
is,<br>
>><br>
>>
define i1
@foo() {<br>
>> ;
CHECK-LABEL:
@foo(<br>
>> ;
CHECK-NEXT:
ret i1 false<br>
>> %m
= call i8*
@malloc(i32 1)<br>
>> %z
= icmp eq i8*
%m, null<br>
>>
call void
@free(i8* %m)<br>
>> ret
i1 %z<br>
>> }<br>
>><br>
>>
According to <a
moz-do-not-send="true"
href="http://www.cplusplus.com/reference/cstdlib/malloc/"
target="_blank">http://www.cplusplus.com/reference/cstdlib/malloc/</a>,
malloc may<br>
>>
return null if
this memory
allocation
fails. So why
we assume
malloc()<br>
>>
always returns
a non-null
pointer here?<br>
>><br>
>> I
think we can
do such
optimization
with operator
new, because
new never<br>
>>
returns null.
But for all
malloc like
allocation(malloc,
calloc, and
new<br>
>> with
std::nothrow),
we shouldn't
do this.<br>
>><br>
>> That
regression
test exists
for a long
time, I'm not
sure if
there's any<br>
>>
special
reason. Does
anybody know
about this?<br>
>><br>
>> --<br>
>>
Thanks,<br>
>><br>
>> Kevin
Qin<br>
>><br>
>>
_______________________________________________<br>
>> LLVM
Developers
mailing list<br>
>> <a
moz-do-not-send="true"
href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>
<a
moz-do-not-send="true"
href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
>> <a
moz-do-not-send="true"
href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
>><br>
</div>
</div>
</blockquote>
</div>
<br>
<br
clear="all">
<div><br>
</div>
</div>
</div>
<span><font
color="#888888">--
<br>
<div>
<div dir="ltr">Best
Regards,
<div><br>
</div>
<div>Kevin Qin</div>
</div>
</div>
</font></span></div>
</div>
</div>
<br>
_______________________________________________<br>
LLVM Developers
mailing list<br>
<a
moz-do-not-send="true"
href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>
<a
moz-do-not-send="true"
href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a
moz-do-not-send="true"
href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br>
</blockquote>
</div>
<br>
</div>
</div>
</div>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a moz-do-not-send="true"
href="mailto:LLVMdev@cs.uiuc.edu"
target="_blank">LLVMdev@cs.uiuc.edu</a>
<a moz-do-not-send="true"
href="http://llvm.cs.uiuc.edu"
target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a moz-do-not-send="true"
href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev"
target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br>
</blockquote>
</div>
</div>
</div>
<br>
</div>
</div>
</blockquote>
</div>
<br>
<br clear="all">
<div><br>
</div>
-- <br>
<div>
<div dir="ltr">Best Regards,
<div><br>
</div>
<div>Kevin Qin</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a moz-do-not-send="true" href="mailto:LLVMdev@cs.uiuc.edu"
target="_blank">LLVMdev@cs.uiuc.edu</a> <a
moz-do-not-send="true" href="http://llvm.cs.uiuc.edu"
target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a moz-do-not-send="true"
href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev"
target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</blockquote>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
LLVM Developers mailing list
<a class="moz-txt-link-abbreviated" href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a> <a class="moz-txt-link-freetext" href="http://llvm.cs.uiuc.edu">http://llvm.cs.uiuc.edu</a>
<a class="moz-txt-link-freetext" href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a>
</pre>
</blockquote>
<br>
<br>
<pre class="moz-signature" cols="72">--
Richard Osborne | XMOS
<a class="moz-txt-link-freetext" href="http://www.xmos.com">http://www.xmos.com</a>
</pre>
</body>
</html>