<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>