[llvm-bugs] [Bug 45937] New: If you specify -O2, the result is incorrect. (Cause problems with GVN pass)

via llvm-bugs llvm-bugs at lists.llvm.org
Fri May 15 03:56:34 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=45937

            Bug ID: 45937
           Summary: If you specify -O2, the result is incorrect. (Cause
                    problems with GVN pass)
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Scalar Optimizations
          Assignee: unassignedbugs at nondot.org
          Reporter: fj8765ah at aa.jp.fujitsu.com
                CC: llvm-bugs at lists.llvm.org

If -O2 is specified in the following program, the result will be incorrect.

% diff O0 O2
1c1
< ((float *)a + 38)[2] = 3.010000
---
> ((float *)a + 38)[2] = 7.059145

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

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200515/f53fe189/attachment.html>


More information about the llvm-bugs mailing list