-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Unable to assign paired register for inline asm with 64-bit data on ARM #13994
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Fixed by patches: |
I'm still seeing this issue (on almost identical code) in llvm rev. 176491, clang rev. 176480. Code in question is: static inline void tf_write_reg64(void *comm_buffer, u64 value)
} Generated code is: .Ltmp7: (Note the ldrexd r5, [r3] -- r5 is an odd register) |
(changing platform to Other/All as the target is arm w/ any OS) |
when you use it assumes %0, %1, %2 are independent regs. Instead, you should use %n %Hn.
1: ldrexd r4, [r1] |
Fix |
Bernhard's patch has fixed my issue in both runtime and compile time. Also I know a commit of LLVM in which these problems do not happen: baabdec Here the list of commits applied on the same file as Bernhard's patch after this commit. |
In fact baabdec commit + Weiming Zhao patch solved the problem at that point. But in the current HEAD the problem is still happening. |
Fixed in r188643 |
mentioned in issue llvm/llvm-bugzilla-archive#18926 |
$ cat test.s // llvm-mc -triple=riscv32 -mattr=+Xsecure test.s -show-inst // llvm-mc -triple=riscv32 -mattr=+Xsecure test.s -filetype=obj -o test.o // llvm-objdump -d --mattr=+Xsecure test.o .text .globl _start _start: # Test the new instructions: openstealth.rol x5, x6, x7 openstealth.ror x5, x6, x7 openstealth.rori x5, x6, 13 # Return or jump to an infinite loop to avoid crashing ret $ llvm-mc -triple=riscv32 -mattr=+Xsecure test.s -show-inst .text .globl _start _start: openstealth.rol t0, t1, t2 # <MCInst llvm#13993 XSECURE_ROL # <MCOperand Reg:48> # <MCOperand Reg:49> # <MCOperand Reg:50>> openstealth.ror t0, t1, t2 # <MCInst llvm#13994 XSECURE_ROR # <MCOperand Reg:48> # <MCOperand Reg:49> # <MCOperand Reg:50>> openstealth.rori t0, t1, 13 # <MCInst llvm#13995 XSECURE_RORI # <MCOperand Reg:48> # <MCOperand Reg:49> # <MCOperand Imm:13>> ret # <MCInst llvm#12777 JALR # <MCOperand Reg:43> # <MCOperand Reg:44> # <MCOperand Imm:0>> $ llvm-objdump -d --mattr=+Xsecure test.o test.o: file format elf32-littleriscv Disassembly of section .text: 00000000 <_start>: 0: 607312b3 openstealth.rol t0, t1, t2 4: 607352b3 openstealth.ror t0, t1, t2 8: 60d35293 openstealth.rori t0, t1, 0xd c: 00008067 ret
$ cat test.s // llvm-mc -triple=riscv32 -mattr=+Xsecure test.s -show-inst // llvm-mc -triple=riscv32 -mattr=+Xsecure test.s -filetype=obj -o test.o // llvm-objdump -d --mattr=+Xsecure test.o .text .globl _start _start: # Test the new instructions: openstealth.rol x5, x6, x7 openstealth.ror x5, x6, x7 openstealth.rori x5, x6, 13 # Return or jump to an infinite loop to avoid crashing ret $ llvm-mc -triple=riscv32 -mattr=+Xsecure test.s -show-inst .text .globl _start _start: openstealth.rol t0, t1, t2 # <MCInst llvm#13993 XSECURE_ROL # <MCOperand Reg:48> # <MCOperand Reg:49> # <MCOperand Reg:50>> openstealth.ror t0, t1, t2 # <MCInst llvm#13994 XSECURE_ROR # <MCOperand Reg:48> # <MCOperand Reg:49> # <MCOperand Reg:50>> openstealth.rori t0, t1, 13 # <MCInst llvm#13995 XSECURE_RORI # <MCOperand Reg:48> # <MCOperand Reg:49> # <MCOperand Imm:13>> ret # <MCInst llvm#12777 JALR # <MCOperand Reg:43> # <MCOperand Reg:44> # <MCOperand Imm:0>> $ llvm-objdump -d --mattr=+Xsecure test.o test.o: file format elf32-littleriscv Disassembly of section .text: 00000000 <_start>: 0: 607312b3 openstealth.rol t0, t1, t2 4: 607352b3 openstealth.ror t0, t1, t2 8: 60d35293 openstealth.rori t0, t1, 0xd c: 00008067 ret $ clang --target=riscv32 -mcpu=attorv32 test.s -c
Extended Description
on ARM, for the following C code:
typedef unsigned long long u64;
void i64_write(u64 *p, u64 val)
{
u64 tmp;
"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)
The text was updated successfully, but these errors were encountered: