Skip to content

Commit 0da6811

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 0d12628 commit 0da6811

File tree

5 files changed

+61
-3
lines changed

5 files changed

+61
-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
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %clang_cc1 %s -triple mips -target-feature +soft-float \
2+
// RUN: -DSOFT_FLOAT_CONSTRAINT_R \
3+
// RUN: -DFLOAT=float -emit-llvm -o - \
4+
// RUN: | FileCheck %s --check-prefix SOFT_FLOAT_CONSTRAINT_R_SINGLE
5+
6+
// RUN: %clang_cc1 %s -triple mips -target-feature +soft-float \
7+
// RUN: -DSOFT_FLOAT_CONSTRAINT_R \
8+
// RUN: -DFLOAT=double -emit-llvm -o - \
9+
// RUN: | FileCheck %s --check-prefix SOFT_FLOAT_CONSTRAINT_R_DOUBLE
10+
11+
#ifdef SOFT_FLOAT_CONSTRAINT_R
12+
// SOFT_FLOAT_CONSTRAINT_R_SINGLE: call void asm sideeffect "", "r,~{$1}"(float %2) #1, !srcloc !2
13+
// SOFT_FLOAT_CONSTRAINT_R_DOUBLE: call void asm sideeffect "", "r,~{$1}"(double %2) #1, !srcloc !2
14+
void read_float(FLOAT* p) {
15+
FLOAT result = *p;
16+
__asm__("" ::"r"(result));
17+
}
18+
#endif // SOFT_FLOAT_CONSTRAINT_R
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %clang_cc1 -triple mips -target-feature +soft-float -DSOFT_FLOAT_NO_CONSTRAINT_F -fsyntax-only -verify %s
2+
3+
#ifdef SOFT_FLOAT_NO_CONSTRAINT_F
4+
void read_float(float p) {
5+
float result = p;
6+
__asm__("" ::"f"(result)); // expected-error{{invalid input constraint 'f' in asm}}
7+
}
8+
#endif // SOFT_FLOAT_NO_CONSTRAINT_F

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);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; RUN: llc -march=mips < %s | FileCheck %s --check-prefix=MIPS32
2+
; RUN: llc -march=mips64 < %s | FileCheck %s --check-prefix=MIPS64
3+
4+
define dso_local void @read_double(ptr nocapture noundef readonly %0) local_unnamed_addr #0 {
5+
%2 = load double, ptr %0, align 8
6+
; MIPS32-LABEL: read_double:
7+
; MIPS32: lw $2, 4($4)
8+
; MIPS32-NEXT: lw $3, 0($4)
9+
; MIPS64-LABEL: read_double:
10+
; MIPS64: ld $2, 0($4)
11+
tail call void asm sideeffect "", "r,~{$1}"(double %2)
12+
ret void
13+
}
14+
15+
define dso_local void @read_float(ptr nocapture noundef readonly %0) local_unnamed_addr #0 {
16+
%2 = load float, ptr %0, align 8
17+
; MIPS32-LABEL: read_float:
18+
; MIPS32: lw $2, 0($4)
19+
; MIPS64-LABEL: read_float:
20+
; MIPS64: lw $2, 0($4)
21+
tail call void asm sideeffect "", "r,~{$1}"(float %2)
22+
ret void
23+
}
24+
25+
attributes #0 = { "target-features"="+soft-float" "use-soft-float"="true" }

0 commit comments

Comments
 (0)