Open calebh opened 6 months ago
@llvm/issue-subscribers-backend-aarch64
Author: Caleb Helbling (calebh)
Hi,
When disabling GlobalISel
with -mllvm --aarch64-enable-global-isel-at-O=-1
, the error you get with -Os
can be seen too.
With godbolt, we can also see that:
GlobalISel
enabled with the previous versions (18.1.0
-> 11.0.1
)11.0.0
(GlobalISel
enabled) with crash in RegBankSelect
errorTwo points:
double
instead of a float
, no errors22
instead of v22
, no error (arm ref)we narrow to the following code,
void myfun() {
// Constraining a float to live in an arbitrary floating point register
// (in this case v22), then using inline assembly causes a crash
register float v22 asm("v22");
asm ("" : "=r"(v22) : : ); // <---------------- LINE A
asm ("" : : "r"(v22) :); // <---------------- LINE B
}
When commenting out either Line A
or Line B
, we get with GlobalISel disabled:
LINE A
-> crashLINE B
-> conversion error message without crash Doing the same with GlobalISel enabled,
LINE A
-> compileLINE B
-> crash@calebh Just to be clear, did you use the asm
directive without any ops, did you get the same result with an assembly instruction ?
@calebh Just to be clear, did you use the
asm
directive without any ops, did you get the same result with an assembly instruction ?
For my application we actually use empty assembly blocks. The asm statements are merely used to trick the compiler into thinking that the v22
variable is live after LINE A
, and LINE B
is inserted just before the return
statement to ensure that the variable lives through the body of the function.
The scenario we're using this trick for is for a micropatch compiler (see https://github.com/purseclab/Patcherex2/issues/24). The register
and asm
blocks are used to gain control over additional registers not covered by the calling convention. The overall goal is to allow the programmer to write micropatches in C-like syntax, for example a x64 micropatch can be written like this:
if (rcx >= r8) {
rdi = rsi * rdx;
}
We then extract the compiled function and insert it into the binary we are patching.
Thanks for pointing out that subregisters (b
, h
, s
, d
, q
) for the v
registers exist. I think I can work around this bug for my application by using those.
I am experiencing a compiler crash when forcing a float variable to live within a certain register, then using that register in some ASM blocks. So far this issue has only cropped up for the Aarch64 project and has not affected my compilation for x64.
Here is an ultra-minimal program that leads to a reproduction:
When using the GCC ARM cross compiler this code compiles just fine, which further supports that this is a clang bug.
Here is the command that I'm running to compile:
The following is outputted to the console:
I have attached the diagnostic files that were requested by the compiler: patch-6b1343.zip
When running with the
-Os
flag, we see an additional error message:patch-e9243f.zip