[llvm-bugs] [Bug 40554] New: misaligned float in PowerPC code causes SIGBUS in OpenBSD/macppc
via llvm-bugs
llvm-bugs at lists.llvm.org
Thu Jan 31 13:58:33 PST 2019
https://bugs.llvm.org/show_bug.cgi?id=40554
Bug ID: 40554
Summary: misaligned float in PowerPC code causes SIGBUS in
OpenBSD/macppc
Product: new-bugs
Version: 7.0
Hardware: Macintosh
OS: OpenBSD
Status: NEW
Severity: normal
Priority: P
Component: new bugs
Assignee: unassignedbugs at nondot.org
Reporter: kernigh at gmail.com
CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org
Created attachment 21415
--> https://bugs.llvm.org/attachment.cgi?id=21415&action=edit
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.
--
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/20190131/e8808ffd/attachment.html>
More information about the llvm-bugs
mailing list