[clang] [llvm] MIPS/clang: Disallow constraint f for softfloat (PR #79116)

YunQiang Su via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 2 03:25:56 PST 2024


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

>From 009bd230a51a1790e6691ae3f104f57af311272f 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] 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 ++
 clang/test/Driver/mips-float.c            | 47 +++++++++++++++++++++++
 llvm/lib/Target/Mips/MipsISelLowering.cpp | 10 +++--
 3 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h
index f46b95abfd75c..2b8ad6645e605 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/Driver/mips-float.c b/clang/test/Driver/mips-float.c
index 2f1b813a15322..34cf7fdfb9b79 100644
--- a/clang/test/Driver/mips-float.c
+++ b/clang/test/Driver/mips-float.c
@@ -102,3 +102,50 @@
 // CHECK-ABI-SOFT-MIPS16: "-target-feature" "+mips16"
 // CHECK-ABI-SOFT-MIPS16: "-msoft-float"
 // CHECK-ABI-SOFT-MIPS16: "-mfloat-abi" "soft"
+
+/// On MIPS, don't accept constraint "f" for soft-float.
+// RUN: not %clang -S %s -o %t.s 2>&1 \
+// RUN:     -target mips-linux-gnu -msoft-float \
+// RUN:     -DSOFT_FLOAT_NO_CONSTRAINT_F \
+// RUN:   | FileCheck --check-prefix=CHECK-SOFTFLOAT-ASM-NO-F %s
+// CHECK-SOFTFLOAT-ASM-NO-F: error: invalid input constraint 'f' in asm
+
+#ifdef SOFT_FLOAT_NO_CONSTRAINT_F
+void read_float(float* p) {
+    float result = *p;
+    __asm__("" ::"f"(result));
+}
+#endif // SOFT_FLOAT_NO_CONSTRAINT_F
+
+/// On MIPS, accept constraint "r" for soft-float.
+// RUN: %clang -S %s -o - -O2 2>&1 \
+// RUN:     -target mips-linux-gnu -msoft-float -mabi=32 \
+// RUN:     -DSOFT_FLOAT_USE_CONSTRAINT_R -DFLOAT=float \
+// RUN:   | FileCheck --check-prefix=CHECK-SOFTFLOAT-ASM-USE-R-3232 %s
+// CHECK-SOFTFLOAT-ASM-USE-R-3232: lw	$2, 0($4)
+//
+// RUN: %clang -S %s -o - -O2 2>&1 \
+// RUN:     -target mips-linux-gnu -msoft-float -mabi=32 \
+// RUN:     -DSOFT_FLOAT_USE_CONSTRAINT_R -DFLOAT=double \
+// RUN:   | FileCheck --check-prefix=CHECK-SOFTFLOAT-ASM-USE-R-3264 %s
+// CHECK-SOFTFLOAT-ASM-USE-R-3264: lw	$2, 4($4)
+// CHECK-SOFTFLOAT-ASM-USE-R-3264: lw	$3, 0($4)
+//
+// RUN: %clang -S %s -o - -O2 2>&1 \
+// RUN:     -target mips-linux-gnu -msoft-float -mabi=64 \
+// RUN:     -DSOFT_FLOAT_USE_CONSTRAINT_R -DFLOAT=float \
+// RUN:   | FileCheck --check-prefix=CHECK-SOFTFLOAT-ASM-USE-R-6432 %s
+// CHECK-SOFTFLOAT-ASM-USE-R-6432: lw	$2, 0($4)
+//
+// RUN: %clang -S %s -o - -O2 2>&1 \
+// RUN:     -target mips-linux-gnu -msoft-float -mabi=64 \
+// RUN:     -DSOFT_FLOAT_USE_CONSTRAINT_R -DFLOAT=double \
+// RUN:   | FileCheck --check-prefix=CHECK-SOFTFLOAT-ASM-USE-R-6464 %s
+// CHECK-SOFTFLOAT-ASM-USE-R-6464: ld	$2, 0($4)
+
+#ifdef SOFT_FLOAT_USE_CONSTRAINT_R
+void read_float(FLOAT* p) {
+    FLOAT result = *p;
+    __asm__("" ::"r"(result));
+}
+#endif // SOFT_FLOAT_USE_CONSTRAINT_R
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index b2812f87914df..97e830cec27ca 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);



More information about the cfe-commits mailing list