[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