diff options
| author | Stuart Cook <Zalathar@users.noreply.github.com> | 2025-09-22 20:25:13 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-22 20:25:13 +1000 |
| commit | 40db498a0f0291dde25380adda38cce29e4668cd (patch) | |
| tree | 2331cb2924fa647e961b7e3e72e23afcd0d72cff /tests/codegen-llvm | |
| parent | d144638f8972f532e03e019bc88760ab4d33aa8b (diff) | |
| parent | 3565b0699d6830dc31732afa96272bcbd1f83606 (diff) | |
| download | rust-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.rs | 48 |
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) } |
