Skip to content

Unable to assign paired register for inline asm with 64-bit data on ARM #13994

Closed
@llvmbot

Description

@llvmbot
Bugzilla Link 13622
Resolution FIXED
Resolved on Feb 21, 2014 05:20
Version trunk
OS All
Blocks llvm/llvm-bugzilla-archive#18926
Attachments test case
Reporter LLVM Bugzilla Contributor
CC @asl,@efriedma-quic,@rengolin,@tinti

Extended Description

on ARM, for the following C code:

typedef unsigned long long u64;

void i64_write(u64 *p, u64 val)
{
u64 tmp;

__asm__ __volatile__(

"1: ldrexd %0, %H0, [%2]\n"
" strexd %0, %3, %H3, [%2]\n"
" teq %0, #​0\n"
" bne 1b"
: "=&r" (tmp), "=Qo" (*p)
: "r" (p), "r" (val)
: "cc");
}

It gives error like:
/tmp/write-D5hDGg.s: Assembler messages:
/tmp/write-D5hDGg.s:14: Error: even register required -- `ldrexd r1,r1,[r0]'

Here is the asm it generates:
i64_write:
@app
1: ldrexd r1, r1, [r0]
strexd r1, r2, r3, [r0]
teq r1, #​0
bne 1b
@NO_APP
bx lr

This is because it assigns r1 to %0 (tmp). However, for 64-bit data, it should allocate even/odd reg pair.

One workaround is to hard code register pairs for i64 types. This is the similar way that ARM deals with ldrexd/strexd intrinsics. (In ARMISelDAGToDAG.cpp, ldrexd/strexd get hard coded registers: R0,R1, before register allocation pass)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzilla

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions