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