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