<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 - If you specify -O2, the result is incorrect. (Cause problems with GVN pass)"
href="https://bugs.llvm.org/show_bug.cgi?id=45937">45937</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>If you specify -O2, the result is incorrect. (Cause problems with GVN pass)
</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>fj8765ah@aa.jp.fujitsu.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>If -O2 is specified in the following program, the result will be incorrect.
% diff O0 O2
1c1
< ((float *)a + 38)[2] = 3.010000
---
<span class="quote">> ((float *)a + 38)[2] = 7.059145</span >
- a.c
#include<stdio.h>
int main(void)
{
double a[29],b[20];
int i, j;
for (i = 0; i < 20; ++i) {
b[i] = 2.01f + 1.f;
((float *)a)[i] = 2.01f * 2.0145f;
((float *)a + 38)[i] = 2.01f * 1.0123f;
}
// loop of problems
for (j = 2; j <= 16; ++j) {
a[j - 1] = ((float *)a)[j] * ((float *)a + 38)[j - 1];
((float *)a + 38)[j - 1] = ((float *)a)[j - 1] + b[j - 1];
}
printf("((float *)a + 38)[2] = %f\n",((float *)a + 38)[2]);
return 0;
}
GVN takes one load instruction out of the loop because of the relationship
between the following two load instructions and performs the optimization used
for the next rotation.
- ((float *)a)[j] load instruction
- ((float *)a)[j -1] load instruction
Optimization Image :
before:
// loop of problems
for (j = 2; j <= 16; ++j) {
a[j - 1] = ((float *)a)[j] * ((float *)a + 38)[j - 1];
((float *)a + 38)[j - 1] = ((float *)a)[j - 1] + b[j - 1]; }
after:
float tmpA_1 = ((float *)a)[1]
// loop of problems
for (j = 2; j <= 16; ++j) {
float tmpA_2 = ((float *)a)[j];
a[j - 1] = tmpA_2 * ((float *)a + 38)[j - 1];
((float *)a + 38)[j - 1] = tmpA_1 + b[j - 1];
tmpA_1 = tmpA_2;
}
However, when j = 2, the store instruction for a[j -1] and the load instruction
for ((float *)a)[j -1] overlap by 4 bytes.
I think the result is strange because of that.
Adding the -mllvm -enable-load-pre=false or -mllvm -enable-pre=false option is
OK.</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>