[llvm-bugs] [Bug 30290] New: clang++ miscompile at -O1 with revision 274385

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Sep 5 23:22:14 PDT 2016


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

            Bug ID: 30290
           Summary: clang++ miscompile at -O1 with revision 274385
           Product: clang
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: LLVM Codegen
          Assignee: unassignedclangbugs at nondot.org
          Reporter: warren_ristow at playstation.sony.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

We have encountered a miscompile for x86_64-unknown-linux-gnu, with
'-march=btver2' at optimization '-O1'.  In the test-cases I found, it passes
with optimizaiton lowered to -O0 or raised to -O2, and it also passes for the
default architecture.  I'd expect that the bug can also manifest at higher
optimization levels, but I haven't found an example.

I've reduced the failure to the test-case appended below, and found that the
failure began happening with r274385 (it still fails with current ToT,
r280692).
The failing and passing behaviors are:

  $ clang++ --version
  clang version 4.0.0 (trunk 280692)
  Target: x86_64-unknown-linux-gnu
  Thread model: posix
  InstalledDir: <....>
  $ clang++ -o test.elf -O1 -march=btver2 test.cpp
  $ ./test.elf
       input:    41  42  43  44  45
      output:    41  42  45  17  17
  FAIL
  $
  $ clang++ -o test.elf -O1               test.cpp
  $ ./test.elf
       input:    41  42  43  44  45
      output:    43  44  45  41  42
  PASS
  $
  $ clang++ -o test.elf -O2 -march=btver2 test.cpp
  $ ./test.elf
       input:    41  42  43  44  45
      output:    43  44  45  41  42
  PASS
  $

Although the failure of this test-case began happening with r274385 (as was
the case with the program this was reduced from), I _suspect_ that the
underlying bug is older than that, because in reducing the original program, I
also encountered a test-case that fails in a similar way with significantly
older compilers.  Specifically, I found a very similar test-case that fails
with llvm 3.6 (passes with llvm 3.5).  I'm guessing that the recent change of
r274385 is correct, and it's just that the old bug is now more likely to
manifest.  I haven't bisected down precisely when the older failure began to
happen.  I'll put that similar test-case that fails even with older compilers
in the next post here.  (I'm filing this against Clang / LLVM Codegen, because
that's what changed with r274385.  However, if my guess is right, that's
probably the wrong area.)

Note that bug 28603 is generally about failures appearing since r274385.  But
in the discussion there, the failing test-cases were all examples of broken
user-code that was exposed by r274385.  I believe the test-case below is legal
code, but as I said above, I'm suspicious that r274385 itself is just exposing
an older latent problem.


With that, here is the test-case that began failing with r274385:

//////////////////////////////// test.cpp ////////////////////////////////
extern "C" void printf(...);

int srcData[] = {41, 42, 43, 44, 45};
const int nElems = sizeof(srcData) / sizeof(srcData[0]);

struct Container {
  Container(int i) { mData = i; }
  int mData;
};

struct Wrapper {
  int unusedInt;
  long unusedLong;
  Wrapper(Container* p) : mPtr(p) {}
  Container* mPtr;
};

struct ContainerVector {
  Container* firstElem;
  Container* lastElem;
  ContainerVector() : firstElem(0), lastElem(0) { }
  Container* ptrToElem(int inx) { return firstElem + inx; }
  void allocVec(int n_elems) {
    Container* newVec = (Container*) operator new(sizeof(Container) * n_elems);
    firstElem = newVec;
    lastElem = newVec + n_elems;
    for (int i = 0; i < n_elems; ++i)
      ptrToElem(i)->mData = 17;
  }
};

static void printVec(ContainerVector cv, const char* msg)
{
  printf("%10s:  ", msg);
  for (int i = 0; i < nElems; ++i)
    printf(" %3d", cv.ptrToElem(i)->mData);
  printf("\n");
}

static Wrapper copy(Wrapper wSrcStart, Wrapper wSrcEnd, Wrapper wDst) {
  Container *cSrc, *cEnd, *cDst;
  cSrc = wSrcStart.mPtr;   cEnd = wSrcEnd.mPtr;   cDst = wDst.mPtr;
  for (; cSrc != cEnd; ++cDst, ++cSrc)
    *cDst = *cSrc;
  wDst.mPtr = cDst;
  return wDst;
}

static void copyWithRotateLeft(Wrapper wStartSrc, Wrapper wStartDstSrc,
                               Wrapper wEndSrc, Wrapper wDst) {
  wDst = copy(wStartDstSrc, wEndSrc, wDst);
  copy(wStartSrc, wStartDstSrc, wDst);
}

int main() {
  ContainerVector src, dst;
  src.allocVec(nElems);
  dst.allocVec(nElems);
  for (int i = 0; i < nElems; ++i)
    src.ptrToElem(i)->mData = srcData[i];
  printVec(src, "input");
  copyWithRotateLeft(Wrapper(src.firstElem), Wrapper(src.firstElem + 2),
                     Wrapper(src.lastElem), Wrapper(dst.firstElem));
  printVec(dst, "output");
  printf("%s\n", (((dst.ptrToElem(4))->mData != 42) ? "FAIL" : "PASS"));
}
//////////////////////////////////////////////////////////////////////////

-- 
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/20160906/5352dd0d/attachment-0001.html>


More information about the llvm-bugs mailing list