From 0c8e36bb3052b217aebcd8bd2154cc31618caf4f Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 29 Nov 2024 03:01:33 +0900 Subject: [PATCH] Fix target_feature handling in freg of LoongArch inline assembly --- compiler/rustc_target/src/asm/loongarch.rs | 2 +- .../bad-reg.loongarch64_lp64d.stderr | 38 ++++++++++++ .../bad-reg.loongarch64_lp64s.stderr | 62 +++++++++++++++++++ tests/ui/asm/loongarch/bad-reg.rs | 45 ++++++++++++++ 4 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr create mode 100644 tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr create mode 100644 tests/ui/asm/loongarch/bad-reg.rs diff --git a/compiler/rustc_target/src/asm/loongarch.rs b/compiler/rustc_target/src/asm/loongarch.rs index b1c01d27cadd6..b4ea6fc592a8c 100644 --- a/compiler/rustc_target/src/asm/loongarch.rs +++ b/compiler/rustc_target/src/asm/loongarch.rs @@ -38,7 +38,7 @@ impl LoongArchInlineAsmRegClass { ) -> &'static [(InlineAsmType, Option)] { match self { Self::reg => types! { _: I8, I16, I32, I64, F32, F64; }, - Self::freg => types! { _: F32, F64; }, + Self::freg => types! { f: F32; d: F64; }, } } } diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr new file mode 100644 index 0000000000000..0e54411965012 --- /dev/null +++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr @@ -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 + diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr new file mode 100644 index 0000000000000..6d0410dc6a13f --- /dev/null +++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr @@ -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 + diff --git a/tests/ui/asm/loongarch/bad-reg.rs b/tests/ui/asm/loongarch/bad-reg.rs new file mode 100644 index 0000000000000..c5288cc78b71f --- /dev/null +++ b/tests/ui/asm/loongarch/bad-reg.rs @@ -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 + } +}