<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 - New ARM constant pool optimization passes wrongly aligned data to NEON load optimization"
href="https://bugs.llvm.org/show_bug.cgi?id=32394">32394</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>New ARM constant pool optimization passes wrongly aligned data to NEON load optimization
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>Other
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</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>Backend: ARM
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>llvm@joakim.fea.st
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=18155" name="attach_18155" title="llvm IR, @.arrayliteral is the constant in question">attachment 18155</a> <a href="attachment.cgi?id=18155&action=edit" title="llvm IR, @.arrayliteral is the constant in question">[details]</a></span>
llvm IR, @.arrayliteral is the constant in question
This issue was discovered from running the tests for the D llvm compiler, ldc,
on Android/ARM. Several tests segfault with llvm 4.0, but not with 3.9.1,
because they pass array literals to test functions.
Disassembly shows that the new constant pool optimization places the array
constant right after the calling function, but doesn't account for the fact
that the called function may be using NEON instructions to load the array,
which could depend on 128-bit alignment.
As the array constant isn't necessarily 128-bit word aligned, the NEON load
will fail. Interestingly some tests that failed then pass at higher
optimization levels, because the array constant randomly happens to be 128-bit
word aligned, depending on the length of the optimized function before it.
If I disable the constant pool optimization with --arm-promote-constant=false,
the problem goes away: all tests pass again. I've boiled down the issue to the
following sample D code, extracted from a test:
void main() {
import core.stdc.stdio:printf;
void testIt(size_t numBits, size_t[] bitsToTest...){
printf("numBits is %d\n", numBits);
foreach(b; bitsToTest)
printf("each of bitsToTest is %d\n", b);
}
testIt(100, 0, 1, 31, 63, 85);
}
Without optimization, it runs fine, but once any optimizations are applied, it
segfaults. gdb shows that it fails at this instruction:
vld1.64 {d16-d17}, [r0 :128]!
because r0 isn't 128-bit word aligned, which is what the NEON instruction is
expecting. I've attached the IR and disassembly for the failing executable, ie
with the constant pool optimization applied. More discussion of this issue can
found on the ldc github:
<a href="https://github.com/ldc-developers/ldc/issues/2024#issuecomment-287523479">https://github.com/ldc-developers/ldc/issues/2024#issuecomment-287523479</a>
I tried reproducing this bug using clang 4.0, but for some reason it wasn't
specifying 128-bit word alignment for its NEON vld1.64 loads, so I wasn't able
to trigger it with the code I tried. I didn't spend much time with clang,
maybe it can be hit that way too.</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>