[llvm-bugs] [Bug 32394] New: New ARM constant pool optimization passes wrongly aligned data to NEON load optimization

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Mar 23 08:30:13 PDT 2017


https://bugs.llvm.org/show_bug.cgi?id=32394

            Bug ID: 32394
           Summary: New ARM constant pool optimization passes wrongly
                    aligned data to NEON load optimization
           Product: libraries
           Version: trunk
          Hardware: Other
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Backend: ARM
          Assignee: unassignedbugs at nondot.org
          Reporter: llvm at joakim.fea.st
                CC: llvm-bugs at lists.llvm.org

Created attachment 18155
  --> https://bugs.llvm.org/attachment.cgi?id=18155&action=edit
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:

https://github.com/ldc-developers/ldc/issues/2024#issuecomment-287523479

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.

-- 
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/20170323/f5a29a6f/attachment-0001.html>


More information about the llvm-bugs mailing list