[clang] [llvm] MIPS/clang: Fix asm constraint for softfloat (PR #79116)

Fangrui Song via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 26 22:06:51 PST 2024


https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/79116

>From 14ea44a352d547f3c2736f16a47f3dad449446f5 Mon Sep 17 00:00:00 2001
From: YunQiang Su <syq at gcc.gnu.org>
Date: Tue, 23 Jan 2024 18:14:48 +0800
Subject: [PATCH 1/2] MIPS/clang: Fix asm constraint for softfloat

This include 2 fixes:
	1. Disallow 'f' for softfloat.
	2. Allow 'r' for softfloat.

Currently, 'f' is accpeted by clang, then
LLVM meet an internal error.

'r' is rejected by LLVM by:
  couldn't allocate input reg for constraint 'r'

Fixes: #64241
---
 clang/lib/Basic/Targets/Mips.h                |  3 +++
 .../CodeGen/Mips/inline-asm-constraints.c     | 18 +++++++++++++
 clang/test/Sema/inline-asm-validate-mips.c    |  8 ++++++
 llvm/lib/Target/Mips/MipsISelLowering.cpp     | 10 +++++---
 .../Mips/inlineasm-constraints-softfloat.ll   | 25 +++++++++++++++++++
 5 files changed, 61 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/CodeGen/Mips/inline-asm-constraints.c
 create mode 100644 clang/test/Sema/inline-asm-validate-mips.c
 create mode 100644 llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll

diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h
index f46b95abfd75c7..2b8ad6645e605f 100644
--- a/clang/lib/Basic/Targets/Mips.h
+++ b/clang/lib/Basic/Targets/Mips.h
@@ -238,6 +238,9 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {
     case 'd': // Equivalent to "r" unless generating MIPS16 code.
     case 'y': // Equivalent to "r", backward compatibility only.
     case 'f': // floating-point registers.
+      if (*Name == 'f' && FloatABI == SoftFloat)
+        return false;
+      LLVM_FALLTHROUGH;
     case 'c': // $25 for indirect jumps
     case 'l': // lo register
     case 'x': // hilo register pair
diff --git a/clang/test/CodeGen/Mips/inline-asm-constraints.c b/clang/test/CodeGen/Mips/inline-asm-constraints.c
new file mode 100644
index 00000000000000..0a4cb0b34570e6
--- /dev/null
+++ b/clang/test/CodeGen/Mips/inline-asm-constraints.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -triple mips -target-feature +soft-float \
+// RUN:            -DSOFT_FLOAT_CONSTRAINT_R \
+// RUN:            -DFLOAT=float -emit-llvm -o - \
+// RUN:      | FileCheck %s --check-prefix SOFT_FLOAT_CONSTRAINT_R_SINGLE
+
+// RUN: %clang_cc1 %s -triple mips -target-feature +soft-float \
+// RUN:            -DSOFT_FLOAT_CONSTRAINT_R \
+// RUN:            -DFLOAT=double -emit-llvm -o - \
+// RUN:      | FileCheck %s --check-prefix SOFT_FLOAT_CONSTRAINT_R_DOUBLE
+
+#ifdef SOFT_FLOAT_CONSTRAINT_R
+// SOFT_FLOAT_CONSTRAINT_R_SINGLE: call void asm sideeffect "", "r,~{$1}"(float %2) #1, !srcloc !2
+// SOFT_FLOAT_CONSTRAINT_R_DOUBLE: call void asm sideeffect "", "r,~{$1}"(double %2) #1, !srcloc !2
+void read_float(FLOAT* p) {
+    FLOAT result = *p;
+    __asm__("" ::"r"(result));
+}
+#endif // SOFT_FLOAT_CONSTRAINT_R
diff --git a/clang/test/Sema/inline-asm-validate-mips.c b/clang/test/Sema/inline-asm-validate-mips.c
new file mode 100644
index 00000000000000..5a123cc5fa79c3
--- /dev/null
+++ b/clang/test/Sema/inline-asm-validate-mips.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple mips -target-feature +soft-float -DSOFT_FLOAT_NO_CONSTRAINT_F -fsyntax-only -verify %s
+
+#ifdef SOFT_FLOAT_NO_CONSTRAINT_F
+void read_float(float p) {
+    float result = p;
+    __asm__("" ::"f"(result)); // expected-error{{invalid input constraint 'f' in asm}}
+}
+#endif // SOFT_FLOAT_NO_CONSTRAINT_F
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index b2812f87914df7..97e830cec27cad 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -4128,14 +4128,18 @@ MipsTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
     case 'd': // Address register. Same as 'r' unless generating MIPS16 code.
     case 'y': // Same as 'r'. Exists for compatibility.
     case 'r':
-      if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 || VT == MVT::i1) {
+      if ((VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 ||
+           VT == MVT::i1) ||
+          (VT == MVT::f32 && Subtarget.useSoftFloat())) {
         if (Subtarget.inMips16Mode())
           return std::make_pair(0U, &Mips::CPU16RegsRegClass);
         return std::make_pair(0U, &Mips::GPR32RegClass);
       }
-      if (VT == MVT::i64 && !Subtarget.isGP64bit())
+      if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat())) &&
+          !Subtarget.isGP64bit())
         return std::make_pair(0U, &Mips::GPR32RegClass);
-      if (VT == MVT::i64 && Subtarget.isGP64bit())
+      if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat())) &&
+          Subtarget.isGP64bit())
         return std::make_pair(0U, &Mips::GPR64RegClass);
       // This will generate an error message
       return std::make_pair(0U, nullptr);
diff --git a/llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll b/llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll
new file mode 100644
index 00000000000000..7e0b7a0c33b55f
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll
@@ -0,0 +1,25 @@
+; RUN: llc  -march=mips < %s | FileCheck %s --check-prefix=MIPS32
+; RUN: llc  -march=mips64 < %s | FileCheck %s --check-prefix=MIPS64
+
+define dso_local void @read_double(ptr nocapture noundef readonly %0) local_unnamed_addr #0 {
+  %2 = load double, ptr %0, align 8
+; MIPS32-LABEL: read_double:
+; MIPS32: lw      $2, 4($4)
+; MIPS32-NEXT: lw      $3, 0($4)
+; MIPS64-LABEL: read_double:
+; MIPS64: ld      $2, 0($4)
+  tail call void asm sideeffect "", "r,~{$1}"(double %2)
+  ret void
+}
+
+define dso_local void @read_float(ptr nocapture noundef readonly %0) local_unnamed_addr #0 {
+  %2 = load float, ptr %0, align 8
+; MIPS32-LABEL: read_float:
+; MIPS32: lw      $2, 0($4)
+; MIPS64-LABEL: read_float:
+; MIPS64: lw      $2, 0($4)
+  tail call void asm sideeffect "", "r,~{$1}"(float %2)
+  ret void
+}
+
+attributes #0 = { "target-features"="+soft-float" "use-soft-float"="true" }

>From 97dd952c6a8a1969b36f2007e675c3fbea73cca6 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Mon, 26 Feb 2024 21:47:19 -0800
Subject: [PATCH 2/2] use separate case handler for f and improve/simplify
 tests

---
 clang/lib/Basic/Targets/Mips.h                |  7 ++--
 .../CodeGen/Mips/inline-asm-constraints.c     | 23 ++++-------
 clang/test/Sema/inline-asm-validate-mips.c    | 13 +++---
 .../Mips/inlineasm-constraints-softfloat.ll   | 41 +++++++++++++++----
 4 files changed, 50 insertions(+), 34 deletions(-)

diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h
index 2b8ad6645e605f..23d4e1b598fa1e 100644
--- a/clang/lib/Basic/Targets/Mips.h
+++ b/clang/lib/Basic/Targets/Mips.h
@@ -237,15 +237,14 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {
     case 'r': // CPU registers.
     case 'd': // Equivalent to "r" unless generating MIPS16 code.
     case 'y': // Equivalent to "r", backward compatibility only.
-    case 'f': // floating-point registers.
-      if (*Name == 'f' && FloatABI == SoftFloat)
-        return false;
-      LLVM_FALLTHROUGH;
     case 'c': // $25 for indirect jumps
     case 'l': // lo register
     case 'x': // hilo register pair
       Info.setAllowsRegister();
       return true;
+    case 'f': // floating-point registers.
+      Info.setAllowsRegister();
+      return FloatABI != SoftFloat;
     case 'I': // Signed 16-bit constant
     case 'J': // Integer 0
     case 'K': // Unsigned 16-bit constant
diff --git a/clang/test/CodeGen/Mips/inline-asm-constraints.c b/clang/test/CodeGen/Mips/inline-asm-constraints.c
index 0a4cb0b34570e6..88afe8735083b4 100644
--- a/clang/test/CodeGen/Mips/inline-asm-constraints.c
+++ b/clang/test/CodeGen/Mips/inline-asm-constraints.c
@@ -1,18 +1,11 @@
-// RUN: %clang_cc1 %s -triple mips -target-feature +soft-float \
-// RUN:            -DSOFT_FLOAT_CONSTRAINT_R \
-// RUN:            -DFLOAT=float -emit-llvm -o - \
-// RUN:      | FileCheck %s --check-prefix SOFT_FLOAT_CONSTRAINT_R_SINGLE
+// RUN: %clang_cc1 -emit-llvm -triple mips -target-feature +soft-float %s -o - | FileCheck %s --check-prefix=SOFT_FLOAT
 
-// RUN: %clang_cc1 %s -triple mips -target-feature +soft-float \
-// RUN:            -DSOFT_FLOAT_CONSTRAINT_R \
-// RUN:            -DFLOAT=double -emit-llvm -o - \
-// RUN:      | FileCheck %s --check-prefix SOFT_FLOAT_CONSTRAINT_R_DOUBLE
+// SOFT_FLOAT: call void asm sideeffect "", "r,~{$1}"(float %1)
+void read_float(float *p) {
+  __asm__("" ::"r"(*p));
+}
 
-#ifdef SOFT_FLOAT_CONSTRAINT_R
-// SOFT_FLOAT_CONSTRAINT_R_SINGLE: call void asm sideeffect "", "r,~{$1}"(float %2) #1, !srcloc !2
-// SOFT_FLOAT_CONSTRAINT_R_DOUBLE: call void asm sideeffect "", "r,~{$1}"(double %2) #1, !srcloc !2
-void read_float(FLOAT* p) {
-    FLOAT result = *p;
-    __asm__("" ::"r"(result));
+// SOFT_FLOAT: call void asm sideeffect "", "r,~{$1}"(double %1)
+void read_double(double *p) {
+  __asm__("" :: "r"(*p));
 }
-#endif // SOFT_FLOAT_CONSTRAINT_R
diff --git a/clang/test/Sema/inline-asm-validate-mips.c b/clang/test/Sema/inline-asm-validate-mips.c
index 5a123cc5fa79c3..7da248fe417b5c 100644
--- a/clang/test/Sema/inline-asm-validate-mips.c
+++ b/clang/test/Sema/inline-asm-validate-mips.c
@@ -1,8 +1,9 @@
-// RUN: %clang_cc1 -triple mips -target-feature +soft-float -DSOFT_FLOAT_NO_CONSTRAINT_F -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple mips64 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple mips64 -target-feature +soft-float -fsyntax-only -verify=softfloat %s
 
-#ifdef SOFT_FLOAT_NO_CONSTRAINT_F
-void read_float(float p) {
-    float result = p;
-    __asm__("" ::"f"(result)); // expected-error{{invalid input constraint 'f' in asm}}
+// expected-no-diagnostics
+
+void test_f(float p) {
+  float result = p;
+  __asm__("" :: "f"(result)); // softfloat-error{{invalid input constraint 'f' in asm}}
 }
-#endif // SOFT_FLOAT_NO_CONSTRAINT_F
diff --git a/llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll b/llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll
index 7e0b7a0c33b55f..705570f808ce00 100644
--- a/llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll
+++ b/llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll
@@ -1,23 +1,46 @@
-; RUN: llc  -march=mips < %s | FileCheck %s --check-prefix=MIPS32
-; RUN: llc  -march=mips64 < %s | FileCheck %s --check-prefix=MIPS64
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -march=mips < %s | FileCheck %s --check-prefix=MIPS32
+; RUN: llc -march=mips64 < %s | FileCheck %s --check-prefix=MIPS64
 
 define dso_local void @read_double(ptr nocapture noundef readonly %0) local_unnamed_addr #0 {
-  %2 = load double, ptr %0, align 8
 ; MIPS32-LABEL: read_double:
-; MIPS32: lw      $2, 4($4)
-; MIPS32-NEXT: lw      $3, 0($4)
+; MIPS32:       # %bb.0:
+; MIPS32-NEXT:    lw $2, 4($4)
+; MIPS32-NEXT:    lw $3, 0($4)
+; MIPS32-NEXT:    #APP
+; MIPS32-NEXT:    #NO_APP
+; MIPS32-NEXT:    jr $ra
+; MIPS32-NEXT:    nop
+;
 ; MIPS64-LABEL: read_double:
-; MIPS64: ld      $2, 0($4)
+; MIPS64:       # %bb.0:
+; MIPS64-NEXT:    ld $2, 0($4)
+; MIPS64-NEXT:    #APP
+; MIPS64-NEXT:    #NO_APP
+; MIPS64-NEXT:    jr $ra
+; MIPS64-NEXT:    nop
+  %2 = load double, ptr %0, align 8
   tail call void asm sideeffect "", "r,~{$1}"(double %2)
   ret void
 }
 
 define dso_local void @read_float(ptr nocapture noundef readonly %0) local_unnamed_addr #0 {
-  %2 = load float, ptr %0, align 8
 ; MIPS32-LABEL: read_float:
-; MIPS32: lw      $2, 0($4)
+; MIPS32:       # %bb.0:
+; MIPS32-NEXT:    lw $2, 0($4)
+; MIPS32-NEXT:    #APP
+; MIPS32-NEXT:    #NO_APP
+; MIPS32-NEXT:    jr $ra
+; MIPS32-NEXT:    nop
+;
 ; MIPS64-LABEL: read_float:
-; MIPS64: lw      $2, 0($4)
+; MIPS64:       # %bb.0:
+; MIPS64-NEXT:    lw $2, 0($4)
+; MIPS64-NEXT:    #APP
+; MIPS64-NEXT:    #NO_APP
+; MIPS64-NEXT:    jr $ra
+; MIPS64-NEXT:    nop
+  %2 = load float, ptr %0, align 8
   tail call void asm sideeffect "", "r,~{$1}"(float %2)
   ret void
 }



More information about the cfe-commits mailing list