<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 - Wrong codegen after r337498"
   href="https://bugs.llvm.org/show_bug.cgi?id=38309">38309</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Wrong codegen after r337498
          </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>Interprocedural Optimizations
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>david.green@arm.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>This is a testcase that needs to be compiled with:
clang test.c -O3 -fno-vectorize -fno-unroll-loops -o test.axf



static void test(short *Input, short *Output, short InputSize, short
OutputSize) {
  int i;
  int j;

  for (j = 0; j < OutputSize; j++) {
    int Sum = 0;
    for (i = 0; i < InputSize - j; i++)
      Sum += Input[i+j];
    Output[j] = Sum;
  }
}
void test(short *Input, short *Output, short InputSize, short OutputSize);

static short g_data[] = {16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0,
0};
int main() {
  short *other = malloc(16 * sizeof(short));
  test(g_data, other, 16, 8);
  printf("%d\n", other[0]);
  printf("%d\n", other[1]);
  printf("%d\n", other[2]);
  printf("%d\n", other[3]);
  printf("%d\n", other[4]);
  printf("%d\n", other[5]);
  printf("%d\n", other[6]);
  printf("%d\n", other[7]);
  return 0;
}



test.axf should then print:
128
112
96
80
64
48
32
16

The test includes this data:
static short g_data[] = {16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0,
0};
Which use to come out of clang as:
@g_data = internal global <{ i16, i16, i16, i16, i16, i16, i16, i16, [8 x i16]
}>
But now after rC337498 looks like:
@g_data = internal global <{ [8 x i16], [8 x i16] }> ...


The problem seems to be that after all the inlining, GlobalOpt turns that
g_data into
@g_data.0 = internal unnamed_addr constant [8 x i16] ...
i.e it throws away the second half with the 0's. So we end up reading
jibberish.

I'm not sure which part of this is wrong. My understanding is that accessing
structs like that in C would be UB, but for IR I think it may be allowed. Which
suggests it's GlobalOpt not doing the correct thing splitting up the struct,
but that code has been there for a very long time...</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>