<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - [InstCombine] Instcombine deletes call of 'new' function that has side effects after r325630"
href="https://bugs.llvm.org/show_bug.cgi?id=36476">36476</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[InstCombine] Instcombine deletes call of 'new' function that has side effects after r325630
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>new bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>ilia.taraban@intel.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>This test fails at with wrong result after r325630:
================= nice.cpp ============
#include <stdlib.h>
#include <stdio.h>
extern void *operator new(size_t size)
{
printf("Happy ending\n");
exit(0);
return malloc(size);
}
struct S { int a;};
int main ()
{
S *s = new S;
printf("Bad ending\n");
printf("%x\n", s -> a);
return 0;
}
=======================================
<span class="quote">>>> clang -v</span >
clang version 7.0.0 (trunk 325762)
Target: x86_64-unknown-linux-gnu
Thread model: posix
...
<span class="quote">>>> clang -o nice.exe nice.cpp -O0
>>> ./nice.exe</span >
Happy ending
<span class="quote">>>> clang -o nice.exe nice.cpp -O1
>>> ./nice.exe</span >
Bad ending
Illegal instruction (core dumped)
<span class="quote">>>> clang -o nice.exe nice.cpp -mllvm -opt-bisect-limit :</span >
BISECT: running pass (15) Simplify the CFG on function (_Znwm)
-> Happy ending
BISECT: running pass (16) Combine redundant instructions on function (main)
-> Bad ending
============ nice-before.ll ===========
...
; Function Attrs: nobuiltin uwtable
define dso_local noalias i8* @_Znwm(i64) local_unnamed_addr #0 {
%2 = call i32 @puts(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @str,
i64 0, i64 0))
call void @exit(i32 0) #5
unreachable
}
; Function Attrs: norecurse uwtable
define dso_local i32 @main() local_unnamed_addr #3 {
%1 = call i8* @_Znwm(i64 undef) #6
%2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x
i8]* @.str.1, i32 0, i32 0))
%3 = getelementptr inbounds %struct.S, %struct.S* undef, i32 0, i32 0
%4 = load i32, i32* %3, align 4, !tbaa !2
%5 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x
i8]* @.str.2, i32 0, i32 0), i32 %4)
ret i32 0
}
...
=======================================
<span class="quote">>>> opt nice-before.ll -instcombine -o nice-after.ll -S</span >
============ nice-after.ll ===========
...
; Function Attrs: norecurse uwtable
define dso_local i32 @main() local_unnamed_addr #3 {
%puts = call i32 @puts(i8* getelementptr inbounds ([11 x i8], [11 x i8]*
@str.1, i64 0, i64 0))
store i32 undef, i32* null, align 536870912
%1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x
i8]* @.str.2, i64 0, i64 0), i32 undef)
ret i32 0
}
...
=======================================
This started giving wrong behavior after r325630
[<a href="https://reviews.llvm.org/rL325630">https://reviews.llvm.org/rL325630</a>]
---------------------------------------
r325630 | d0k | 2018-02-20 23:00:33 +0100 (Tue, 20 Feb 2018) | 5 lines
[MemoryBuiltins] Check nobuiltin status when identifying calls to free.
This is usually not a problem because this code's main purpose is
eliminating unused new/delete pairs. We got deletes of nullptr or
nobuiltin deletes of builtin new wrong though.
---------------------------------------</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>