[LLVMbugs] [Bug 18864] New: llvm 3.5 fails to compile inline assembler on ARM

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sun Feb 16 19:29:13 PST 2014


http://llvm.org/bugs/show_bug.cgi?id=18864

            Bug ID: 18864
           Summary: llvm 3.5 fails to compile inline assembler on ARM
           Product: clang
           Version: trunk
          Hardware: Other
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Frontend
          Assignee: unassignedclangbugs at nondot.org
          Reporter: mikulas at artax.karlin.mff.cuni.cz
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

This is an example code that uses hardware divider and neon on ARM:

int divide(int a, int b)
{
        int result;
        asm (".cpu cortex-a15 \n sdiv %0, %1, %2" : "=r"(result) : "r"(a),
"r"(b));
        return result;
}

int count_bits(char a)
{
        char result;
        asm (".fpu neon-vfpv4 \n vld1.8 d0[0], [%1] \n vcnt.8 d0, d0 \n vst1.8
d0[0], [%0]" :: "r"(&result), "r"(&a) : "d0", "memory");
        return result;
}

int printf(const char *,...);

int main(void)
{
        printf("7 / 2 = %d\n", divide(7, 2));
        printf("count_bits(123) = %d\n", count_bits(123));
        return 0;
}

The above example works with gcc and with llvm/clang 3.4. With llvm/clang 3.5
I get the following errors:

asm-div.c:4:26: error: instruction requires: divide in ARM
        asm (".cpu cortex-a15 \n sdiv %0, %1, %2" : "=r"(result) : "r"(a),
"r"(b));
                                ^
<inline asm>:2:2: note: instantiated into assembly here
 sdiv r0, r0, r1
 ^
asm-div.c:11:26: error: invalid operand for instruction
        asm (".fpu neon-vfpv4 \n vld1.8 d0[0], [%1] \n vcnt.8 d0, d0 \n vst1.8
d0[0], [%0]" :: "r"(&result), "r"(&a) : "d0", "memory");
                                ^
<inline asm>:2:11: note: instantiated into assembly here
 vld1.8 d0[0], [r1]
          ^
asm-div.c:11:48: error: instruction requires: NEON
        asm (".fpu neon-vfpv4 \n vld1.8 d0[0], [%1] \n vcnt.8 d0, d0 \n vst1.8
d0[0], [%0]" :: "r"(&result), "r"(&a) : "d0", "memory");
                                                      ^
<inline asm>:3:2: note: instantiated into assembly here
 vcnt.8 d0, d0
 ^
asm-div.c:11:65: error: invalid operand for instruction
        asm (".fpu neon-vfpv4 \n vld1.8 d0[0], [%1] \n vcnt.8 d0, d0 \n vst1.8
d0[0], [%0]" :: "r"(&result), "r"(&a) : "d0", "memory");
                                                                       ^
<inline asm>:4:11: note: instantiated into assembly here
 vst1.8 d0[0], [r0]
          ^
4 errors generated.


Clang 3.5, for some reason, attemps to parse the content of the asm statement
(shouldn't it be parsed by the assembler, not clang?) and fails with those
errors.

These errors can be avoided by passing "-mcpu=cortex-a15" to clang, however it
is
not a proper solution - note that some ARM processors have hardware divide
instruction or neon and some don't. Therefore, the correct way to use the
hardware divider or neon is to read processor capabilities from
"/proc/self/auxv"
at the start of the program, set a flag if the divider (or neon) is present,
and
call the above pieces of assembler conditionally, with slower fallback
implementation for processors that don't have these features. If we compiled
the
program with "-mcpu=cortex-a15", it wouldn't work at all on processors without
hardware division and neon, which is not intended.

The version that fails is "3.5~svn197556-1ubuntu1" from Ubuntu ARM port.

-- 
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/20140217/97585b02/attachment.html>


More information about the llvm-bugs mailing list