Skip to content

Commit afacada

Browse files
committed
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
1 parent d386c40 commit afacada

File tree

3 files changed

+57
-3
lines changed

3 files changed

+57
-3
lines changed

clang/lib/Basic/Targets/Mips.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {
238238
case 'd': // Equivalent to "r" unless generating MIPS16 code.
239239
case 'y': // Equivalent to "r", backward compatibility only.
240240
case 'f': // floating-point registers.
241+
if (*Name == 'f' && FloatABI == SoftFloat)
242+
return false;
243+
LLVM_FALLTHROUGH;
241244
case 'c': // $25 for indirect jumps
242245
case 'l': // lo register
243246
case 'x': // hilo register pair

clang/test/Driver/mips-float.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,50 @@
102102
// CHECK-ABI-SOFT-MIPS16: "-target-feature" "+mips16"
103103
// CHECK-ABI-SOFT-MIPS16: "-msoft-float"
104104
// CHECK-ABI-SOFT-MIPS16: "-mfloat-abi" "soft"
105+
106+
/// On MIPS, don't accept constraint "f" for soft-float.
107+
// RUN: not %clang -S %s -o %t.s 2>&1 \
108+
// RUN: -target mips-linux-gnu -msoft-float \
109+
// RUN: -DSOFT_FLOAT_NO_CONSTRAINT_F \
110+
// RUN: | FileCheck --check-prefix=CHECK-SOFTFLOAT-ASM-NO-F %s
111+
// CHECK-SOFTFLOAT-ASM-NO-F: error: invalid input constraint 'f' in asm
112+
113+
#ifdef SOFT_FLOAT_NO_CONSTRAINT_F
114+
void read_float(float* p) {
115+
float result = *p;
116+
__asm__("" ::"f"(result));
117+
}
118+
#endif // SOFT_FLOAT_NO_CONSTRAINT_F
119+
120+
/// On MIPS, accept constraint "r" for soft-float.
121+
// RUN: %clang -S %s -o - -O2 2>&1 \
122+
// RUN: -target mips-linux-gnu -msoft-float -mabi=32 \
123+
// RUN: -DSOFT_FLOAT_USE_CONSTRAINT_R -DFLOAT=float \
124+
// RUN: | FileCheck --check-prefix=CHECK-SOFTFLOAT-ASM-USE-R-3232 %s
125+
// CHECK-SOFTFLOAT-ASM-USE-R-3232: lw $2, 0($4)
126+
//
127+
// RUN: %clang -S %s -o - -O2 2>&1 \
128+
// RUN: -target mips-linux-gnu -msoft-float -mabi=32 \
129+
// RUN: -DSOFT_FLOAT_USE_CONSTRAINT_R -DFLOAT=double \
130+
// RUN: | FileCheck --check-prefix=CHECK-SOFTFLOAT-ASM-USE-R-3264 %s
131+
// CHECK-SOFTFLOAT-ASM-USE-R-3264: lw $2, 4($4)
132+
// CHECK-SOFTFLOAT-ASM-USE-R-3264: lw $3, 0($4)
133+
//
134+
// RUN: %clang -S %s -o - -O2 2>&1 \
135+
// RUN: -target mips-linux-gnu -msoft-float -mabi=64 \
136+
// RUN: -DSOFT_FLOAT_USE_CONSTRAINT_R -DFLOAT=float \
137+
// RUN: | FileCheck --check-prefix=CHECK-SOFTFLOAT-ASM-USE-R-6432 %s
138+
// CHECK-SOFTFLOAT-ASM-USE-R-6432: lw $2, 0($4)
139+
//
140+
// RUN: %clang -S %s -o - -O2 2>&1 \
141+
// RUN: -target mips-linux-gnu -msoft-float -mabi=64 \
142+
// RUN: -DSOFT_FLOAT_USE_CONSTRAINT_R -DFLOAT=double \
143+
// RUN: | FileCheck --check-prefix=CHECK-SOFTFLOAT-ASM-USE-R-6464 %s
144+
// CHECK-SOFTFLOAT-ASM-USE-R-6464: ld $2, 0($4)
145+
146+
#ifdef SOFT_FLOAT_USE_CONSTRAINT_R
147+
void read_float(FLOAT* p) {
148+
FLOAT result = *p;
149+
__asm__("" ::"r"(result));
150+
}
151+
#endif // SOFT_FLOAT_USE_CONSTRAINT_R

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4128,14 +4128,18 @@ MipsTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
41284128
case 'd': // Address register. Same as 'r' unless generating MIPS16 code.
41294129
case 'y': // Same as 'r'. Exists for compatibility.
41304130
case 'r':
4131-
if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 || VT == MVT::i1) {
4131+
if ((VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 ||
4132+
VT == MVT::i1) ||
4133+
(VT == MVT::f32 && Subtarget.useSoftFloat())) {
41324134
if (Subtarget.inMips16Mode())
41334135
return std::make_pair(0U, &Mips::CPU16RegsRegClass);
41344136
return std::make_pair(0U, &Mips::GPR32RegClass);
41354137
}
4136-
if (VT == MVT::i64 && !Subtarget.isGP64bit())
4138+
if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat())) &&
4139+
!Subtarget.isGP64bit())
41374140
return std::make_pair(0U, &Mips::GPR32RegClass);
4138-
if (VT == MVT::i64 && Subtarget.isGP64bit())
4141+
if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat())) &&
4142+
Subtarget.isGP64bit())
41394143
return std::make_pair(0U, &Mips::GPR64RegClass);
41404144
// This will generate an error message
41414145
return std::make_pair(0U, nullptr);

0 commit comments

Comments
 (0)