[PATCH] D105142: RFC: Implementing new mechanism for hard register operands to inline asm as a constraint.
Anirudh Prasad via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 7 08:06:51 PDT 2021
anirudhp updated this revision to Diff 356961.
anirudhp added a comment.
- Disable constraint simplification when you already have a constraint of the form {...}. Constraint simplification is usually done character by character, with different targets having different implementations.
- Furthermore, a constraint of the form {...} already maps to the LLVM inline assembly IR that tells the backend to allocate a suitable physical register.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D105142/new/
https://reviews.llvm.org/D105142
Files:
clang/lib/CodeGen/CGStmt.cpp
clang/test/CodeGen/x86-asm-register-constraint-mix.c
Index: clang/test/CodeGen/x86-asm-register-constraint-mix.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/x86-asm-register-constraint-mix.c
@@ -0,0 +1,63 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O2 -emit-llvm %s -o - | FileCheck %s
+
+unsigned long foo(unsigned long addr, unsigned long a0,
+ unsigned long a1, unsigned long a2,
+ unsigned long a3, unsigned long a4,
+ unsigned long a5) {
+ register unsigned long result asm("rax");
+ register unsigned long addr1 asm("rax") = addr;
+ register unsigned long b0 asm("rdi") = a0;
+ register unsigned long b1 asm("rsi") = a1;
+ register unsigned long b2 asm("rdx") = a2;
+ register unsigned long b3 asm("rcx") = a3;
+ register unsigned long b4 asm("r8") = a4;
+ register unsigned long b5 asm("r9") = a5;
+
+ // CHECK: tail call i64 asm "call *$1", "={rax},{rax},{rdi},{rsi},{rdx},{rcx},{r8},{r9},{rax},~{dirflag},~{fpsr},~{flags}"(i64 %addr, i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 undef)
+ asm("call *%1"
+ : "+r" (result)
+ : "r"(addr1), "r"(b0), "r"(b1), "r"(b2), "r"(b3), "r"(b4), "r"(b5));
+ return result;
+}
+
+unsigned long foo1(unsigned long addr, unsigned long a0,
+ unsigned long a1, unsigned long a2,
+ unsigned long a3, unsigned long a4,
+ unsigned long a5) {
+ unsigned long result;
+ unsigned long addr1 = addr;
+ unsigned long b0 = a0;
+ unsigned long b1 = a1;
+ unsigned long b2 = a2;
+ unsigned long b3 = a3;
+ unsigned long b4 = a4;
+ unsigned long b5 = a5;
+
+ // CHECK: tail call i64 asm "call *$1", "={rax},{rax},{rdi},{rsi},{rdx},{rcx},{r8},{r9},{rax},~{dirflag},~{fpsr},~{flags}"(i64 %addr, i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 undef)
+ asm("call *%1"
+ : "+{rax}" (result)
+ : "{rax}"(addr1), "{rdi}"(b0), "{rsi}"(b1), "{rdx}"(b2), "{rcx}"(b3), "{r8}"(b4), "{r9}"(b5));
+ return result;
+}
+
+unsigned long foo2(unsigned long addr, unsigned long a0,
+ unsigned long a1, unsigned long a2,
+ unsigned long a3, unsigned long a4,
+ unsigned long a5) {
+ register unsigned long result asm("rax");
+ unsigned long addr1 = addr;
+ unsigned long b0 = a0;
+ register unsigned long b1 asm ("rsi") = a1;
+ unsigned long b2 = a2;
+ unsigned long b3 = a3;
+ register unsigned long b4 asm ("r8") = a4;
+ unsigned long b5 = a5;
+
+ // CHECK: tail call i64 asm "call *$1", "={rax},{rax},{rdi},{rsi},{rdx},{rcx},{r8},{r9},{rax},~{dirflag},~{fpsr},~{flags}"(i64 %addr, i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 undef)
+ asm("call *%1"
+ : "+r" (result)
+ : "{rax}"(addr1), "{rdi}"(b0), "r"(b1), "{rdx}"(b2), "{rcx}"(b3), "r"(b4), "{r9}"(b5));
+ return result;
+}
+
Index: clang/lib/CodeGen/CGStmt.cpp
===================================================================
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -1966,6 +1966,13 @@
static std::string
SimplifyConstraint(const char *Constraint, const TargetInfo &Target,
SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=nullptr) {
+ // If we have only the {...} constraint, do not do any simplifications. This already
+ // maps to the lower level LLVM inline assembly IR that tells the backend to allocate
+ // a specific register. Any validations would have already been done in the Sema stage
+ // or will be done in the AddVariableConstraints function.
+ if (Constraint[0] == '{' || (Constraint[0] == '&' && Constraint[1] == '{'))
+ return std::string(Constraint);
+
std::string Result;
while (*Constraint) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D105142.356961.patch
Type: text/x-patch
Size: 3764 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210707/ee57c5a1/attachment.bin>
More information about the cfe-commits
mailing list