[llvm-bugs] [Bug 48862] New: Inline assembly allocated register clash with multi-register constraints
via llvm-bugs
llvm-bugs at lists.llvm.org
Sun Jan 24 01:56:46 PST 2021
https://bugs.llvm.org/show_bug.cgi?id=48862
Bug ID: 48862
Summary: Inline assembly allocated register clash with
multi-register constraints
Product: libraries
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: Register Allocator
Assignee: unassignedbugs at nondot.org
Reporter: nva280 at nn.kiev.ua
CC: llvm-bugs at lists.llvm.org, quentin.colombet at gmail.com
Consider the following sample program (targeting Linux/x86-64):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
unsigned arg1 = strtoul(argv[1], NULL, 0);
unsigned arg2 = strtoul(argv[2], NULL, 0);
asm(
"mov %[arg1], %%ecx\n\t"
"add %[arg2], %[arg1]\n\t"
"add %[arg2], %%ecx\n\t"
"xchg %%ecx, %[arg2]"
: [arg1] "+&abdSD" (arg1), [arg2] "+&abdSD" (arg2)
:
: "cc", "ecx");
printf("%u %u\n", arg1, arg2);
}
(xchg is used just for easy grepping of compiled instructions in listing. This
is just an example crafted to reproduce the issue, far from real code, but
clear enough.)
With GCC, it works as expected - different registers are assigned to arg1 and
arg2, for example:
11bf: e8 cc fe ff ff callq 1090 <strtoul at plt>
11c4: 89 da mov %ebx,%edx
11c6: 89 d1 mov %edx,%ecx
11c8: 01 c2 add %eax,%edx
11ca: 01 c1 add %eax,%ecx
11cc: 91 xchg %eax,%ecx
(so, arg1 in edx, arg2 in eax)
But, compiling with Clang (confirmed on all from 6.0 to trunk) results in
assigning the same register for arg1 and arg2:
401174: e8 d7 fe ff ff callq 401050 <strtoul at plt>
401179: 44 89 f0 mov %r14d,%eax ; <--
40117c: 89 c1 mov %eax,%ecx
40117e: 01 c0 add %eax,%eax ; <-- so, arg1 and
arg2 both in eax
401180: 01 c1 add %eax,%ecx
401182: 91 xchg %eax,%ecx
The issue remains with multiple variations as e.g.: + instead of +& in
constraint strings; numeric forms like %0 to address operands; replacing xchg
with another rare instruction; and so on.
The issue is of importance on x86 because a lots of its instructions are
allowing only fixed registers, but a desire to alleviate allocation causes
constraint suggestion as explicit list except 1-2 reserved ones.
A workaround is accessible to use generic constraints like 'r' while marking
all disallowed registers as clobbered, but Iʼm uncertain whether it wonʼt
explode with "rm" or analogs.
Discussed also at https://stackoverflow.com/q/65644864 (with an explicit
suggestion this is really a bug).
--
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/20210124/5a711578/attachment.html>
More information about the llvm-bugs
mailing list