Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
attrs.push(llvm::AttributeKind::WillReturn.create_attr(self.cx.llcx));
} else if options.contains(InlineAsmOptions::NOMEM) {
attrs.push(llvm::MemoryEffects::InaccessibleMemOnly.create_attr(self.cx.llcx));
} else {
// LLVM doesn't have an attribute to represent ReadOnly + SideEffect
} else if options.contains(InlineAsmOptions::READONLY) {
attrs.push(llvm::MemoryEffects::ReadOnlyNotPure.create_attr(self.cx.llcx));
}
attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs });

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ pub(crate) enum MemoryEffects {
None,
ReadOnly,
InaccessibleMemOnly,
ReadOnlyNotPure,
}

/// LLVMOpcode
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ enum class LLVMRustMemoryEffects {
None,
ReadOnly,
InaccessibleMemOnly,
ReadOnlyNotPure,
};

extern "C" LLVMAttributeRef
Expand All @@ -568,6 +569,10 @@ LLVMRustCreateMemoryEffectsAttr(LLVMContextRef C,
case LLVMRustMemoryEffects::InaccessibleMemOnly:
return wrap(Attribute::getWithMemoryEffects(
*unwrap(C), MemoryEffects::inaccessibleMemOnly()));
case LLVMRustMemoryEffects::ReadOnlyNotPure:
return wrap(Attribute::getWithMemoryEffects(
*unwrap(C),
MemoryEffects::readOnly() | MemoryEffects::inaccessibleMemOnly()));
default:
report_fatal_error("bad MemoryEffects.");
}
Expand Down
48 changes: 48 additions & 0 deletions tests/codegen-llvm/asm/readonly-not-pure.rs
Original file line number Diff line number Diff line change
@@ -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) }
Loading