[clang] [clang][sema] forbid '+f' on output register (PR #75208)

via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 12 08:16:00 PST 2023


https://github.com/knightXun updated https://github.com/llvm/llvm-project/pull/75208

>From 38e6bcf970d62deb5c6fa2ba33ae817d39124c6a Mon Sep 17 00:00:00 2001
From: knightXun <badgangkiller at gmail.com>
Date: Tue, 12 Dec 2023 23:57:56 +0800
Subject: [PATCH 1/2] [clang][sema] forbid '+f' on output register to align
 with GCC asm: "+f" is not allowed to be used on output register.

fix issue: https://github.com/llvm/llvm-project/issues/75019
---
 clang/lib/Basic/TargetInfo.cpp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 6cd5d618a4acaa..57a81e03bc484f 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -717,8 +717,15 @@ bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
   if (*Name != '=' && *Name != '+')
     return false;
 
-  if (*Name == '+')
+  if (*Name == '+') {
     Info.setIsReadWrite();
+    // To align with GCC asm: "=f" is not allowed, the
+    // operand constraints must select a class with a single reg.
+    auto Flag = Name + 1;
+    if (Flag && *Flag == 'f') {
+      return false;
+    }
+  }
 
   Name++;
   while (*Name) {

>From b2522c92196ec401f8b5d92da8ec2b90b7872fda Mon Sep 17 00:00:00 2001
From: knightXun <badgangkiller at gmail.com>
Date: Wed, 13 Dec 2023 00:15:46 +0800
Subject: [PATCH 2/2] add ut

---
 clang/test/Sema/asm.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c
index 630a5e85dd9131..a490e9fb5e9322 100644
--- a/clang/test/Sema/asm.c
+++ b/clang/test/Sema/asm.c
@@ -359,3 +359,17 @@ void test19(long long x)
   // FIXME: This case should be supported by codegen, but it fails now.
   asm ("" : "=rm" (x): "0" (e)); // expected-error {{unsupported inline asm: input with type 'st_size128' (aka 'struct _st_size128') matching output with type 'long long'}}
 }
+
+void test20()
+{
+  double f00 = 0.0; 
+  double f01 = 0.0; 
+  double f10 = 0.0; 
+  double f11 = 0.0;
+  int mem;
+  asm volatile ("" : "+f" (f00), "+f" (f01), "+f" (f10), "+f" (f11), "+m" (mem) :: "memory"); // expected-error {{invalid output constraint '+f' in asm}}
+  asm volatile ("" : "+r" (f00), "+f" (f01), "+f" (f10), "+f" (f11), "+m" (mem) :: "memory"); // expected-error {{invalid output constraint '+f' in asm}}
+  asm volatile ("" : "+r" (f00), "+r" (f01), "+f" (f10), "+f" (f11), "+m" (mem) :: "memory"); // expected-error {{invalid output constraint '+f' in asm}}
+  asm volatile ("" : "+r" (f00), "+r" (f01), "+r" (f10), "+f" (f11), "+m" (mem) :: "memory"); // expected-error {{invalid output constraint '+f' in asm}}
+  asm volatile ("" : "+r" (f00), "+r" (f01), "+r" (f10), "+r" (f11), "+m" (mem) :: "memory"); // no-error
+}
\ No newline at end of file



More information about the cfe-commits mailing list