about summary refs log tree commit diff
path: root/tests/codegen-llvm
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-09-22 20:25:13 +1000
committerGitHub <noreply@github.com>2025-09-22 20:25:13 +1000
commit40db498a0f0291dde25380adda38cce29e4668cd (patch)
tree2331cb2924fa647e961b7e3e72e23afcd0d72cff /tests/codegen-llvm
parentd144638f8972f532e03e019bc88760ab4d33aa8b (diff)
parent3565b0699d6830dc31732afa96272bcbd1f83606 (diff)
downloadrust-40db498a0f0291dde25380adda38cce29e4668cd.tar.gz
rust-40db498a0f0291dde25380adda38cce29e4668cd.zip
Rollup merge of #146791 - folkertdev:readonly-not-pure, r=nikic,joshtriplett
emit attribute for readonly non-pure inline assembly

fixes https://github.com/rust-lang/rust/issues/146761

Provide a better `MemoryEffects` to LLVM when an inline assembly block specifies `readonly` but not `pure`. That means that the assembly block may not perform any writes, but that there still may be side effects from its instructions.

I haven't been able to find a case yet where this actually matters, though. So the test checks that the right attribute is applied, but the generated assembly is equivalent to not specifying `readonly` at all.

r? ````@nikic````
cc ````@Amanieu````
Diffstat (limited to 'tests/codegen-llvm')
-rw-r--r--tests/codegen-llvm/asm/readonly-not-pure.rs48
1 files changed, 48 insertions, 0 deletions
diff --git a/tests/codegen-llvm/asm/readonly-not-pure.rs b/tests/codegen-llvm/asm/readonly-not-pure.rs
new file mode 100644
index 00000000000..a3c0e276c7f
--- /dev/null
+++ b/tests/codegen-llvm/asm/readonly-not-pure.rs
@@ -0,0 +1,48 @@
+//@ add-core-stubs
+//@ compile-flags: -Copt-level=3 --target x86_64-unknown-linux-gnu
+//@ needs-llvm-components: x86
+
+#![crate_type = "rlib"]
+#![feature(no_core)]
+#![no_core]
+
+// Test that when an inline assembly block specifies `readonly` but not `pure`, a detailed
+// `MemoryEffects` is provided to LLVM: this assembly block is not allowed to perform writes,
+// but it may have side-effects.
+
+extern crate minicore;
+use minicore::*;
+
+pub static mut VAR: i32 = 0;
+
+// CHECK-LABEL: @no_options
+// CHECK: call i32 asm
+#[no_mangle]
+pub unsafe fn no_options() -> i32 {
+    VAR = 1;
+    let _ignored: i32;
+    asm!("mov {0}, 1", out(reg) _ignored);
+    VAR
+}
+
+// CHECK-LABEL: @readonly_pure
+// CHECK-NOT: call i32 asm
+#[no_mangle]
+pub unsafe fn readonly_pure() -> i32 {
+    VAR = 1;
+    let _ignored: i32;
+    asm!("mov {0}, 1", out(reg) _ignored, options(pure, readonly));
+    VAR
+}
+
+// CHECK-LABEL: @readonly_not_pure
+// CHECK: call i32 asm {{.*}} #[[ATTR:[0-9]+]]
+#[no_mangle]
+pub unsafe fn readonly_not_pure() -> i32 {
+    VAR = 1;
+    let _ignored: i32;
+    asm!("mov {0}, 1", out(reg) _ignored, options(readonly));
+    VAR
+}
+
+// CHECK: attributes #[[ATTR]] = { nounwind memory(read, inaccessiblemem: readwrite) }