Skip to content

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

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions