<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 - misaligned float in PowerPC code causes SIGBUS in OpenBSD/macppc"
href="https://bugs.llvm.org/show_bug.cgi?id=40554">40554</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>misaligned float in PowerPC code causes SIGBUS in OpenBSD/macppc
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</td>
</tr>
<tr>
<th>Version</th>
<td>7.0
</td>
</tr>
<tr>
<th>Hardware</th>
<td>Macintosh
</td>
</tr>
<tr>
<th>OS</th>
<td>OpenBSD
</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>new bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>kernigh@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=21415" name="attach_21415" title="try to avoid misaligned floats">attachment 21415</a> <a href="attachment.cgi?id=21415&action=edit" title="try to avoid misaligned floats">[details]</a></span>
try to avoid misaligned floats
clang -O2 can emit PowerPC instructions like lfs or lfsx that load or store a
misaligned float. Such instruction crashes with SIGBUS in OpenBSD/macppc.
This crash happened with clang 6 and clang 7, not with gcc. This crash only
happened if I told clang to optimize. This seems to be a bad optimization in
LLVM's PowerPC target.
This is a simple example of the problem:
$ cat bustest.c
#include <stdio.h>
struct {int i; char c[5];} s = {0, {0, 0x42, 0xf6, 0xe9, 0x79}};
int main() {
union {float f; int i;} u;
u.i = (s.c[1]<<24) + (s.c[2]<<16) + (s.c[3]<<8) + s.c[4];
printf("%g\n", u.f);
}
$ clang -O2 -o bustest bustest.c
$ ./bustest
Bus error (core dumped)
$ egdb bustest bustest.core
...
#0 0x0610055c in main ()
(gdb) disas $pc, $pc +4
Dump of assembler code from 0x610055c to 0x6100560:
=> 0x0610055c <main+48>: lfs f1,5(r3)
End of assembler dump.
(gdb) print 5 + $r3
$1 = 101847053
The example assumes that int has 4-bytes and float is a 4-byte IEEE float. The
correct output is 123.456. The idea is to read 4 bytes from a file (but this
example hardcodes the bytes), convert them from big to native endian, and
interpret them as a float. The target is big-endian PowerPC, so one may
optimize away the endian conversion, but LLVM has optimized too far by using
`lfs f1,5(r3)` to load float register f1 directly from the array. This is
misalignment because 5(r3) is not a multiple of 4.
I believe that lfs/stfs, lfd/stfd, lfsx, and other instructions for loading or
storing a float register need the address to be a multiple of 4. This minimum
4-byte alignment is for both 4-byte floats and 8-byte doubles (but 8-byte
doubles prefer 8-byte alignment). Freescale Semiconductor, *Programming
Environments Manual for 32-Bit Implementations of the PowerPC Architecture*
(MPCFPE32B.pdf), section 6.5.6 "Alignment Interrupt", says that a memory access
may fail because, "An operand of a floating-point load or store instruction is
not word-aligned." A word has 4 bytes. The processor in my PowerBook G4
(running OpenBSD/macppc) is an MPC7447A.
The attached patch tries to fix the problem. The patch is for llvm-project.git
master. I can't run master (I say why in #40553), but I am using the same
patch in clang 7.0.1, where it seems to fix my example. I don't know if my
patch is correct, because I don't understand LLVM's code.</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>