diff options
author | YunQiang Su <syq@debian.org> | 2024-02-27 14:08:36 +0800 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2024-02-27 09:18:54 -0800 |
commit | 461274b81d8641eab64d494accddc81d7db8a09e (patch) | |
tree | e1be320fbeea1122cd0d243440f8463cf003ac68 | |
parent | e2182a6b91f5001bd9b52e3b1fe6beac434e5fe5 (diff) | |
download | llvm-llvmorg-18.1.0-rc4.zip llvm-llvmorg-18.1.0-rc4.tar.gz llvm-llvmorg-18.1.0-rc4.tar.bz2 |
MIPS: Fix asm constraints "f" and "r" for softfloat (#79116)llvmorg-18.1.0-rc4llvmorg-18.1.0
This include 2 fixes:
1. Disallow 'f' for softfloat.
2. Allow 'r' for softfloat.
Currently, 'f' is accpeted by clang, then LLVM meets an internal error.
'r' is rejected by LLVM by: couldn't allocate input reg for constraint
'r'.
Fixes: #64241, #63632
---------
Co-authored-by: Fangrui Song <i@maskray.me>
(cherry picked from commit c88beb4112d5bbf07d76a615ab7f13ba2ba023e6)
-rw-r--r-- | clang/lib/Basic/Targets/Mips.h | 4 | ||||
-rw-r--r-- | clang/test/CodeGen/Mips/inline-asm-constraints.c | 11 | ||||
-rw-r--r-- | clang/test/Sema/inline-asm-validate-mips.c | 9 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsISelLowering.cpp | 10 | ||||
-rw-r--r-- | llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll | 48 |
5 files changed, 78 insertions, 4 deletions
diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index f46b95a..23d4e1b 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -237,12 +237,14 @@ public: 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. 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 new file mode 100644 index 0000000..88afe87 --- /dev/null +++ b/clang/test/CodeGen/Mips/inline-asm-constraints.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm -triple mips -target-feature +soft-float %s -o - | FileCheck %s --check-prefix=SOFT_FLOAT + +// SOFT_FLOAT: call void asm sideeffect "", "r,~{$1}"(float %1) +void read_float(float *p) { + __asm__("" ::"r"(*p)); +} + +// SOFT_FLOAT: call void asm sideeffect "", "r,~{$1}"(double %1) +void read_double(double *p) { + __asm__("" :: "r"(*p)); +} 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 0000000..7da248f --- /dev/null +++ b/clang/test/Sema/inline-asm-validate-mips.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple mips64 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple mips64 -target-feature +soft-float -fsyntax-only -verify=softfloat %s + +// expected-no-diagnostics + +void test_f(float p) { + float result = p; + __asm__("" :: "f"(result)); // softfloat-error{{invalid input constraint 'f' in asm}} +} diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index d431d3d..88b226e 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 0000000..705570f --- /dev/null +++ b/llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll @@ -0,0 +1,48 @@ +; 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 { +; MIPS32-LABEL: read_double: +; 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: # %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 { +; MIPS32-LABEL: read_float: +; 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: # %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 +} + +attributes #0 = { "target-features"="+soft-float" "use-soft-float"="true" } |