<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 - Unnecessary load not eliminated"
href="https://bugs.llvm.org/show_bug.cgi?id=47895">47895</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Unnecessary load not eliminated
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</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>Scalar Optimizations
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>david.bolvansky@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Extracted from PR47887
Testcase:
void foo(int *p,int *q,int x) {
*p=x;
*q=x;
if(*p!=x) /* false */
__builtin_abort();
}
Clang -O3:
foo(int*, int*, int): # @foo(int*, int*, int)
push rax
mov dword ptr [rdi], edx
mov dword ptr [rsi], edx
cmp dword ptr [rdi], edx
jne .LBB0_2
pop rax
ret
.LBB0_2:
call abort
GCC can remove unnecessary load.
foo(int*, int*, int):
mov DWORD PTR [rdi], edx
mov DWORD PTR [rsi], edx
ret
Analysis of the problem by Florian Hahn (thx!):
"In the case above neither of the stores is dead. The load is unnecessary, but
only because we store the same value to both p and q. `store i32 x, i32* q` may
alias `load p`, but it stores the same value as the store to p.
We should be able to handle this with MemorySSA, possibly as an extension of
DSE, but it won't fit directly in the main elimination loop and will need some
extra code."</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>