emit attribute for readonly non-pure inline assembly
This commit is contained in:
parent
1d23da6b73
commit
3565b0699d
4 changed files with 56 additions and 2 deletions
|
|
@ -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 });
|
||||
|
||||
|
|
|
|||
|
|
@ -710,6 +710,7 @@ pub(crate) enum MemoryEffects {
|
|||
None,
|
||||
ReadOnly,
|
||||
InaccessibleMemOnly,
|
||||
ReadOnlyNotPure,
|
||||
}
|
||||
|
||||
/// LLVMOpcode
|
||||
|
|
|
|||
|
|
@ -553,6 +553,7 @@ enum class LLVMRustMemoryEffects {
|
|||
None,
|
||||
ReadOnly,
|
||||
InaccessibleMemOnly,
|
||||
ReadOnlyNotPure,
|
||||
};
|
||||
|
||||
extern "C" LLVMAttributeRef
|
||||
|
|
@ -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.");
|
||||
}
|
||||
|
|
|
|||
48
tests/codegen-llvm/asm/readonly-not-pure.rs
Normal file
48
tests/codegen-llvm/asm/readonly-not-pure.rs
Normal file
|
|
@ -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…
Add table
Add a link
Reference in a new issue