Rollup merge of #133587 - taiki-e:loongarch-asm-freg, r=Amanieu
Fix target_feature handling in freg of LoongArch inline assembly
In LoongArch inline assembly, freg currently always accepts f32/f64 as input/output.
9b4d7c6a40/compiler/rustc_target/src/asm/loongarch.rs (L41)
However, these types actually require f/d target features as in RISC-V.
Otherwise, an (ugly) compile error will occur: https://godbolt.org/z/K61Gq1E9E
f32/f64 without f:
```
error: couldn't allocate output register for constraint '{$f1}'
--> <source>:12:11
|
12 | asm!("", in("$f1") x, lateout("$f1") y);
| ^
```
f64 with f but without d:
```
error: scalar-to-vector conversion failed, possible invalid constraint for vector type
--> <source>:19:11
|
19 | asm!("", in("$f1") x, lateout("$f1") y);
| ^
```
cc ``@heiher``
r? ``@Amanieu``
``@rustbot`` label +O-LoongArch +A-inline-assembly
This commit is contained in:
commit
ab4588a619
4 changed files with 146 additions and 1 deletions
|
@ -38,7 +38,7 @@ impl LoongArchInlineAsmRegClass {
|
|||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
|
||||
Self::freg => types! { _: F32, F64; },
|
||||
Self::freg => types! { f: F32; d: F64; },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
38
tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr
Normal file
38
tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr
Normal file
|
@ -0,0 +1,38 @@
|
|||
error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:22:18
|
||||
|
|
||||
LL | asm!("", out("$r0") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$tp`: reserved for TLS
|
||||
--> $DIR/bad-reg.rs:24:18
|
||||
|
|
||||
LL | asm!("", out("$tp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:26:18
|
||||
|
|
||||
LL | asm!("", out("$sp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$r21`: reserved by the ABI
|
||||
--> $DIR/bad-reg.rs:28:18
|
||||
|
|
||||
LL | asm!("", out("$r21") _);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:30:18
|
||||
|
|
||||
LL | asm!("", out("$fp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:32:18
|
||||
|
|
||||
LL | asm!("", out("$r31") _);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
62
tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr
Normal file
62
tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr
Normal file
|
@ -0,0 +1,62 @@
|
|||
error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:22:18
|
||||
|
|
||||
LL | asm!("", out("$r0") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$tp`: reserved for TLS
|
||||
--> $DIR/bad-reg.rs:24:18
|
||||
|
|
||||
LL | asm!("", out("$tp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:26:18
|
||||
|
|
||||
LL | asm!("", out("$sp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$r21`: reserved by the ABI
|
||||
--> $DIR/bad-reg.rs:28:18
|
||||
|
|
||||
LL | asm!("", out("$r21") _);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:30:18
|
||||
|
|
||||
LL | asm!("", out("$fp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:32:18
|
||||
|
|
||||
LL | asm!("", out("$r31") _);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: register class `freg` requires at least one of the following target features: d, f
|
||||
--> $DIR/bad-reg.rs:36:26
|
||||
|
|
||||
LL | asm!("/* {} */", in(freg) f);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: register class `freg` requires at least one of the following target features: d, f
|
||||
--> $DIR/bad-reg.rs:38:26
|
||||
|
|
||||
LL | asm!("/* {} */", out(freg) _);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: register class `freg` requires at least one of the following target features: d, f
|
||||
--> $DIR/bad-reg.rs:40:26
|
||||
|
|
||||
LL | asm!("/* {} */", in(freg) d);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: register class `freg` requires at least one of the following target features: d, f
|
||||
--> $DIR/bad-reg.rs:42:26
|
||||
|
|
||||
LL | asm!("/* {} */", out(freg) d);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
45
tests/ui/asm/loongarch/bad-reg.rs
Normal file
45
tests/ui/asm/loongarch/bad-reg.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
//@ add-core-stubs
|
||||
//@ needs-asm-support
|
||||
//@ revisions: loongarch64_lp64d loongarch64_lp64s
|
||||
//@[loongarch64_lp64d] compile-flags: --target loongarch64-unknown-linux-gnu
|
||||
//@[loongarch64_lp64d] needs-llvm-components: loongarch
|
||||
//@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat
|
||||
//@[loongarch64_lp64s] needs-llvm-components: loongarch
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(no_core, rustc_attrs)]
|
||||
#![no_core]
|
||||
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
fn f() {
|
||||
let mut x = 0;
|
||||
let mut f = 0.0_f32;
|
||||
let mut d = 0.0_f64;
|
||||
unsafe {
|
||||
// Unsupported registers
|
||||
asm!("", out("$r0") _);
|
||||
//~^ ERROR constant zero cannot be used as an operand for inline asm
|
||||
asm!("", out("$tp") _);
|
||||
//~^ ERROR invalid register `$tp`: reserved for TLS
|
||||
asm!("", out("$sp") _);
|
||||
//~^ ERROR invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
|
||||
asm!("", out("$r21") _);
|
||||
//~^ ERROR invalid register `$r21`: reserved by the ABI
|
||||
asm!("", out("$fp") _);
|
||||
//~^ ERROR invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
|
||||
asm!("", out("$r31") _);
|
||||
//~^ ERROR invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
|
||||
asm!("", out("$f0") _); // ok
|
||||
asm!("/* {} */", in(freg) f);
|
||||
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
|
||||
asm!("/* {} */", out(freg) _);
|
||||
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
|
||||
asm!("/* {} */", in(freg) d);
|
||||
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
|
||||
asm!("/* {} */", out(freg) d);
|
||||
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue