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 <s...@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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits