mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 06:46:33 +00:00
MIPS: Fix asm constraints "f" and "r" for softfloat (#79116)
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)
This commit is contained in:
parent
e2182a6b91
commit
461274b81d
@ -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
|
||||
|
11
clang/test/CodeGen/Mips/inline-asm-constraints.c
Normal file
11
clang/test/CodeGen/Mips/inline-asm-constraints.c
Normal file
@ -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));
|
||||
}
|
9
clang/test/Sema/inline-asm-validate-mips.c
Normal file
9
clang/test/Sema/inline-asm-validate-mips.c
Normal file
@ -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}}
|
||||
}
|
@ -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);
|
||||
|
48
llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll
Normal file
48
llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll
Normal file
@ -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" }
|
Loading…
x
Reference in New Issue
Block a user