Bad codegen for ARM (and maybe others) when optimizing
Dan Olson via digitalmars-d-ldc
digitalmars-d-ldc at puremagic.com
Wed Feb 4 08:15:47 PST 2015
Just a warning to ARM and PPC users. And potentially other CPUs with
similar register files. I've discovered a codegen problem with -O1 and
higher. What happens is that load instructions are being incorrectly
reordered before stores. It is a problem in the LLVM backend. Versions
LLVM-3.5, 3.4, 3.3 have the problem based on my testing, and maybe
earlier.
The result is a program with incorrect results or crashes.
After much digging I discovered it happens in the "top-down list latency
scheduler" pass and a search of llvm bugs brought up for PPC:
http://llvm.org/bugs/show_bug.cgi?id=20280
This looks to be the same problem. All the fixes should be in LLVM-3.6
which I have not tried yet (does LDC work with 3.6?).
Here is a small program which exhibits the problem on ARM (iOS in my case).
---- badopt.d ----
struct A {int value;}
A fun(A a) {return a;}
void foo(A a)
{
A z = fun(a);
import core.stdc.stdio: printf;
printf("%d %d\n", a.value, z.value);
// -O1 prints: 12345678 1
// -O0 prints: 12345678 12345678
}
void main()
{
A a = A(12345678);
foo(a);
}
----
In this case the, the -O1 assembly for foo() as it calls fun() is:
$ ldc2 -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 -float-abi=softfp -O1 -output-s -c badopt.d
// foo gets arg a.value in r0
__D6badopt3fooFS6badopt1AZv:
sub sp, #4
push {r7, lr}
mov r7, sp
sub sp, #4
ldr r1, [r7, #8] <--- out of order
str r0, [r7, #8] <----'
mov r0, sp
bl __D6badopt3funFS6badopt1AZS6badopt1A
More information about the digitalmars-d-ldc
mailing list