about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTaiki Endo <te316e89@gmail.com>2024-10-14 05:30:45 +0900
committerTaiki Endo <te316e89@gmail.com>2024-10-14 05:30:45 +0900
commitd858dfedbbde119f2ea707fea253e99c824ec252 (patch)
tree8297efb9c430d26187bbc45012d47f73f5dc9cc4
parent8f8bee4f60d9d3769f75c70d558c27a95761c554 (diff)
downloadrust-d858dfedbbde119f2ea707fea253e99c824ec252.tar.gz
rust-d858dfedbbde119f2ea707fea253e99c824ec252.zip
Fix clobber_abi and disallow SVE-related registers in Arm64EC inline assembly
-rw-r--r--compiler/rustc_target/src/asm/aarch64.rs37
-rw-r--r--compiler/rustc_target/src/asm/mod.rs17
-rw-r--r--tests/codegen/asm-arm64ec-clobbers.rs36
-rw-r--r--tests/ui/asm/aarch64/aarch64-sve.rs28
-rw-r--r--tests/ui/asm/aarch64/arm64ec-sve.rs31
-rw-r--r--tests/ui/asm/aarch64/arm64ec-sve.stderr14
6 files changed, 143 insertions, 20 deletions
diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs
index 74970a26b23..fdd9adabc8e 100644
--- a/compiler/rustc_target/src/asm/aarch64.rs
+++ b/compiler/rustc_target/src/asm/aarch64.rs
@@ -64,6 +64,7 @@ impl AArch64InlineAsmRegClass {
                 neon: I8, I16, I32, I64, F16, F32, F64, F128,
                     VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2), VecF64(1),
                     VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2);
+                // Note: When adding support for SVE vector types, they must be rejected for Arm64EC.
             },
             Self::preg => &[],
         }
@@ -96,7 +97,7 @@ fn restricted_for_arm64ec(
     _is_clobber: bool,
 ) -> Result<(), &'static str> {
     if arch == InlineAsmArch::Arm64EC {
-        Err("x13, x14, x23, x24, x28, v16-v31 cannot be used for Arm64EC")
+        Err("x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC")
     } else {
         Ok(())
     }
@@ -165,23 +166,23 @@ def_regs! {
         v29: vreg = ["v29", "b29", "h29", "s29", "d29", "q29", "z29"] % restricted_for_arm64ec,
         v30: vreg = ["v30", "b30", "h30", "s30", "d30", "q30", "z30"] % restricted_for_arm64ec,
         v31: vreg = ["v31", "b31", "h31", "s31", "d31", "q31", "z31"] % restricted_for_arm64ec,
-        p0: preg = ["p0"],
-        p1: preg = ["p1"],
-        p2: preg = ["p2"],
-        p3: preg = ["p3"],
-        p4: preg = ["p4"],
-        p5: preg = ["p5"],
-        p6: preg = ["p6"],
-        p7: preg = ["p7"],
-        p8: preg = ["p8"],
-        p9: preg = ["p9"],
-        p10: preg = ["p10"],
-        p11: preg = ["p11"],
-        p12: preg = ["p12"],
-        p13: preg = ["p13"],
-        p14: preg = ["p14"],
-        p15: preg = ["p15"],
-        ffr: preg = ["ffr"],
+        p0: preg = ["p0"] % restricted_for_arm64ec,
+        p1: preg = ["p1"] % restricted_for_arm64ec,
+        p2: preg = ["p2"] % restricted_for_arm64ec,
+        p3: preg = ["p3"] % restricted_for_arm64ec,
+        p4: preg = ["p4"] % restricted_for_arm64ec,
+        p5: preg = ["p5"] % restricted_for_arm64ec,
+        p6: preg = ["p6"] % restricted_for_arm64ec,
+        p7: preg = ["p7"] % restricted_for_arm64ec,
+        p8: preg = ["p8"] % restricted_for_arm64ec,
+        p9: preg = ["p9"] % restricted_for_arm64ec,
+        p10: preg = ["p10"] % restricted_for_arm64ec,
+        p11: preg = ["p11"] % restricted_for_arm64ec,
+        p12: preg = ["p12"] % restricted_for_arm64ec,
+        p13: preg = ["p13"] % restricted_for_arm64ec,
+        p14: preg = ["p14"] % restricted_for_arm64ec,
+        p15: preg = ["p15"] % restricted_for_arm64ec,
+        ffr: preg = ["ffr"] % restricted_for_arm64ec,
         #error = ["x19", "w19"] =>
             "x19 is used internally by LLVM and cannot be used as an operand for inline asm",
         #error = ["x29", "w29", "fp", "wfp"] =>
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 73ae1ae96ae..4b539eb8e20 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -890,6 +890,7 @@ pub enum InlineAsmClobberAbi {
     Arm,
     AArch64,
     AArch64NoX18,
+    Arm64EC,
     RiscV,
     LoongArch,
     S390x,
@@ -932,7 +933,7 @@ impl InlineAsmClobberAbi {
                 _ => Err(&["C", "system", "efiapi"]),
             },
             InlineAsmArch::Arm64EC => match name {
-                "C" | "system" => Ok(InlineAsmClobberAbi::AArch64NoX18),
+                "C" | "system" => Ok(InlineAsmClobberAbi::Arm64EC),
                 _ => Err(&["C", "system"]),
             },
             InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name {
@@ -1033,7 +1034,6 @@ impl InlineAsmClobberAbi {
                     p0, p1, p2, p3, p4, p5, p6, p7,
                     p8, p9, p10, p11, p12, p13, p14, p15,
                     ffr,
-
                 }
             },
             InlineAsmClobberAbi::AArch64NoX18 => clobbered_regs! {
@@ -1052,7 +1052,20 @@ impl InlineAsmClobberAbi {
                     p0, p1, p2, p3, p4, p5, p6, p7,
                     p8, p9, p10, p11, p12, p13, p14, p15,
                     ffr,
+                }
+            },
+            InlineAsmClobberAbi::Arm64EC => clobbered_regs! {
+                AArch64 AArch64InlineAsmReg {
+                    // x13 and x14 cannot be used in Arm64EC.
+                    x0, x1, x2, x3, x4, x5, x6, x7,
+                    x8, x9, x10, x11, x12, x15,
+                    x16, x17, x30,
 
+                    // Technically the low 64 bits of v8-v15 are preserved, but
+                    // we have no way of expressing this using clobbers.
+                    v0, v1, v2, v3, v4, v5, v6, v7,
+                    v8, v9, v10, v11, v12, v13, v14, v15,
+                    // v16-v31, p*, and ffr cannot be used in Arm64EC.
                 }
             },
             InlineAsmClobberAbi::Arm => clobbered_regs! {
diff --git a/tests/codegen/asm-arm64ec-clobbers.rs b/tests/codegen/asm-arm64ec-clobbers.rs
new file mode 100644
index 00000000000..2ec61907947
--- /dev/null
+++ b/tests/codegen/asm-arm64ec-clobbers.rs
@@ -0,0 +1,36 @@
+//@ assembly-output: emit-asm
+//@ compile-flags: --target arm64ec-pc-windows-msvc
+//@ needs-llvm-components: aarch64
+
+#![crate_type = "rlib"]
+#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+
+// CHECK-LABEL: @cc_clobber
+// CHECK: call void asm sideeffect "", "~{cc}"()
+#[no_mangle]
+pub unsafe fn cc_clobber() {
+    asm!("", options(nostack, nomem));
+}
+
+// CHECK-LABEL: @no_clobber
+// CHECK: call void asm sideeffect "", ""()
+#[no_mangle]
+pub unsafe fn no_clobber() {
+    asm!("", options(nostack, nomem, preserves_flags));
+}
+
+// CHECK-LABEL: @clobber_abi
+// CHECK: asm sideeffect "", "={w0},={w1},={w2},={w3},={w4},={w5},={w6},={w7},={w8},={w9},={w10},={w11},={w12},={w15},={w16},={w17},={w30},={q0},={q1},={q2},={q3},={q4},={q5},={q6},={q7},={q8},={q9},={q10},={q11},={q12},={q13},={q14},={q15}"()
+#[no_mangle]
+pub unsafe fn clobber_abi() {
+    asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
+}
diff --git a/tests/ui/asm/aarch64/aarch64-sve.rs b/tests/ui/asm/aarch64/aarch64-sve.rs
new file mode 100644
index 00000000000..8cdc9dd4266
--- /dev/null
+++ b/tests/ui/asm/aarch64/aarch64-sve.rs
@@ -0,0 +1,28 @@
+//@ only-aarch64
+//@ build-pass
+//@ needs-asm-support
+
+#![crate_type = "rlib"]
+#![feature(no_core, rustc_attrs, lang_items)]
+#![no_core]
+
+// AArch64 test corresponding to arm64ec-sve.rs.
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+impl Copy for f64 {}
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+
+fn f(x: f64) {
+    unsafe {
+        asm!("", out("p0") _);
+        asm!("", out("ffr") _);
+    }
+}
diff --git a/tests/ui/asm/aarch64/arm64ec-sve.rs b/tests/ui/asm/aarch64/arm64ec-sve.rs
new file mode 100644
index 00000000000..389b365a754
--- /dev/null
+++ b/tests/ui/asm/aarch64/arm64ec-sve.rs
@@ -0,0 +1,31 @@
+//@ compile-flags: --target arm64ec-pc-windows-msvc
+//@ needs-asm-support
+//@ needs-llvm-components: aarch64
+
+#![crate_type = "rlib"]
+#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
+#![no_core]
+
+// SVE cannot be used for Arm64EC
+// https://github.com/rust-lang/rust/pull/131332#issuecomment-2401189142
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+impl Copy for f64 {}
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+
+fn f(x: f64) {
+    unsafe {
+        asm!("", out("p0") _);
+        //~^ ERROR cannot use register `p0`
+        asm!("", out("ffr") _);
+        //~^ ERROR cannot use register `ffr`
+    }
+}
diff --git a/tests/ui/asm/aarch64/arm64ec-sve.stderr b/tests/ui/asm/aarch64/arm64ec-sve.stderr
new file mode 100644
index 00000000000..3e1a5d57004
--- /dev/null
+++ b/tests/ui/asm/aarch64/arm64ec-sve.stderr
@@ -0,0 +1,14 @@
+error: cannot use register `p0`: x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC
+  --> $DIR/arm64ec-sve.rs:26:18
+   |
+LL |         asm!("", out("p0") _);
+   |                  ^^^^^^^^^^^
+
+error: cannot use register `ffr`: x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC
+  --> $DIR/arm64ec-sve.rs:28:18
+   |
+LL |         asm!("", out("ffr") _);
+   |                  ^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+