<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - [InstCombine] miscompile at -O2 with revision 257897"
   href="https://llvm.org/bugs/show_bug.cgi?id=31808">31808</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[InstCombine] miscompile at -O2 with revision 257897
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.9
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </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>warren_ristow@playstation.sony.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>We have come across an optimization bug causing a run-time failure. The
test-case below runs correctly when compiled at -O0 or -O1, but fails
at -O2.

Tested with Target: x86_64-unknown-linux-gnu

To reproduce:

  $ clang++ -O1 -o test_O1.elf test.cpp
  $ test_O1.elf
  {{BEGIN}}
  0x1c30c28 0x1c30c28 {PASS}
  {{END}}
  $


  $ clang++ -O2 -o test_O2.elf test.cpp
  $ test_O2.elf
  {{BEGIN}}
  0x15aac28 0x15aac28 {FAIL}
  {{END}}
  $

This passed with LLVM 3.8, but fails with LLVM 3.9, and still fails with
current ToT (tested with r293595).

Bisection identifies that the failure began with r257897, which is a
re-commit of a change with the following summary description:

  When comparing two GEP instructions which have the same base pointer
  and one of them has a constant index, it is possible to only compare
  indices, transforming it to a compare with a constant. This removes
  one use for the GEP instruction with the constant index, can reduce
  register pressure and can sometimes lead to removing the comparisson
  entirely.


// ============================================================================
extern "C" {
int printf(const char *, ...);
void *malloc(unsigned long);
void *memcpy(void *, const void *, unsigned long);
}

struct Array {
  unsigned char *m_ArrayData;
  unsigned int m_ReservedSize;
  unsigned int m_Size;

  Array() : m_ArrayData(), m_ReservedSize(0), m_Size(0) {}

  int **End() { return (int **)(m_ArrayData + m_Size * sizeof(int *)); }

  void Reserve(unsigned int newReservedSize) {
    if (m_ReservedSize < newReservedSize) {
      void *newData = malloc(newReservedSize * sizeof(int *));
      if (m_Size) {
        memcpy(newData, m_ArrayData, sizeof(int *) * m_Size);
      }
      m_ArrayData = (unsigned char *)newData;
    }
  }

  void Add() {
    if (m_Size + 1 > m_ReservedSize) {
      Reserve((m_Size * 3 / 2) + 8);
    }

    unsigned int newSize = m_Size + 1;
    m_Size = newSize;

    int *it = (int *)m_ArrayData + newSize - 1;
    *it = 1;
  }
};

struct LoopIter {
  LoopIter(Array &from) : m_Curr((int **)from.m_ArrayData), m_End(from.End())
{}

  operator int **() { return m_Curr; }

  int **m_Curr;
  int **m_End;
};

struct SomeStruct {
  Array m_SomeStruct;

  void AddSomeStruct() { m_SomeStruct.Add(); }
  __attribute__((noinline)) void CheckOne() {
    LoopIter it(m_SomeStruct);
    bool match = (it + 1) == it.m_End;
    printf("%p %p {%s}\n", it + 1, it.m_End, (match ? "PASS" : "FAIL"));
  }
};

int main() {
  printf("{{BEGIN}}\n");
  SomeStruct var;
  var.AddSomeStruct();
  var.CheckOne();
  printf("{{END}}\n");

  return 0;
}

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