mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
cleanup: handle -Zmutable-noalias like -Zbox-noalias
This commit is contained in:
parent
c7572670a1
commit
d165a6d708
@ -34,13 +34,6 @@ pub trait ArgAttributesExt {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_use_mutable_noalias(cx: &CodegenCx<'_, '_>) -> bool {
|
|
||||||
// LLVM prior to version 12 had known miscompiles in the presence of
|
|
||||||
// noalias attributes (see #54878), but we don't support earlier
|
|
||||||
// versions at all anymore. We now enable mutable noalias by default.
|
|
||||||
cx.tcx.sess.opts.unstable_opts.mutable_noalias.unwrap_or(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
const ABI_AFFECTING_ATTRIBUTES: [(ArgAttribute, llvm::AttributeKind); 1] =
|
const ABI_AFFECTING_ATTRIBUTES: [(ArgAttribute, llvm::AttributeKind); 1] =
|
||||||
[(ArgAttribute::InReg, llvm::AttributeKind::InReg)];
|
[(ArgAttribute::InReg, llvm::AttributeKind::InReg)];
|
||||||
|
|
||||||
@ -88,9 +81,6 @@ fn get_attrs<'ll>(this: &ArgAttributes, cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'
|
|||||||
attrs.push(llattr.create_attr(cx.llcx));
|
attrs.push(llattr.create_attr(cx.llcx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if regular.contains(ArgAttribute::NoAliasMutRef) && should_use_mutable_noalias(cx) {
|
|
||||||
attrs.push(llvm::AttributeKind::NoAlias.create_attr(cx.llcx));
|
|
||||||
}
|
|
||||||
} else if cx.tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) {
|
} else if cx.tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) {
|
||||||
// If we're not optimising, *but* memory sanitizer is on, emit noundef, since it affects
|
// If we're not optimising, *but* memory sanitizer is on, emit noundef, since it affects
|
||||||
// memory sanitizer's behavior.
|
// memory sanitizer's behavior.
|
||||||
|
@ -71,12 +71,7 @@ mod attr_impl {
|
|||||||
const NonNull = 1 << 3;
|
const NonNull = 1 << 3;
|
||||||
const ReadOnly = 1 << 4;
|
const ReadOnly = 1 << 4;
|
||||||
const InReg = 1 << 5;
|
const InReg = 1 << 5;
|
||||||
// Due to past miscompiles in LLVM, we use a separate attribute for
|
const NoUndef = 1 << 6;
|
||||||
// &mut arguments, so that the codegen backend can decide whether
|
|
||||||
// or not to actually emit the attribute. It can also be controlled
|
|
||||||
// with the `-Zmutable-noalias` debugging option.
|
|
||||||
const NoAliasMutRef = 1 << 6;
|
|
||||||
const NoUndef = 1 << 7;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,6 +256,11 @@ fn adjust_for_rust_scalar<'tcx>(
|
|||||||
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/326
|
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/326
|
||||||
let noalias_for_box = cx.tcx.sess.opts.unstable_opts.box_noalias.unwrap_or(true);
|
let noalias_for_box = cx.tcx.sess.opts.unstable_opts.box_noalias.unwrap_or(true);
|
||||||
|
|
||||||
|
// LLVM prior to version 12 had known miscompiles in the presence of noalias attributes
|
||||||
|
// (see #54878), so it was conditionally disabled, but we don't support earlier
|
||||||
|
// versions at all anymore. We still support turning it off using -Zmutable-noalias.
|
||||||
|
let noalias_mut_ref = cx.tcx.sess.opts.unstable_opts.mutable_noalias.unwrap_or(true);
|
||||||
|
|
||||||
// `&mut` pointer parameters never alias other parameters,
|
// `&mut` pointer parameters never alias other parameters,
|
||||||
// or mutable global data
|
// or mutable global data
|
||||||
//
|
//
|
||||||
@ -263,15 +268,9 @@ fn adjust_for_rust_scalar<'tcx>(
|
|||||||
// and can be marked as both `readonly` and `noalias`, as
|
// and can be marked as both `readonly` and `noalias`, as
|
||||||
// LLVM's definition of `noalias` is based solely on memory
|
// LLVM's definition of `noalias` is based solely on memory
|
||||||
// dependencies rather than pointer equality
|
// dependencies rather than pointer equality
|
||||||
//
|
|
||||||
// Due to past miscompiles in LLVM, we apply a separate NoAliasMutRef attribute
|
|
||||||
// for UniqueBorrowed arguments, so that the codegen backend can decide whether
|
|
||||||
// or not to actually emit the attribute. It can also be controlled with the
|
|
||||||
// `-Zmutable-noalias` debugging option.
|
|
||||||
let no_alias = match kind {
|
let no_alias = match kind {
|
||||||
PointerKind::SharedMutable
|
PointerKind::SharedMutable | PointerKind::UniqueBorrowedPinned => false,
|
||||||
| PointerKind::UniqueBorrowed
|
PointerKind::UniqueBorrowed => noalias_mut_ref,
|
||||||
| PointerKind::UniqueBorrowedPinned => false,
|
|
||||||
PointerKind::UniqueOwned => noalias_for_box,
|
PointerKind::UniqueOwned => noalias_for_box,
|
||||||
PointerKind::Frozen => true,
|
PointerKind::Frozen => true,
|
||||||
};
|
};
|
||||||
@ -284,10 +283,6 @@ fn adjust_for_rust_scalar<'tcx>(
|
|||||||
if kind == PointerKind::Frozen && !is_return {
|
if kind == PointerKind::Frozen && !is_return {
|
||||||
attrs.set(ArgAttribute::ReadOnly);
|
attrs.set(ArgAttribute::ReadOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
if kind == PointerKind::UniqueBorrowed && !is_return {
|
|
||||||
attrs.set(ArgAttribute::NoAliasMutRef);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
src/test/codegen/noalias-flag.rs
Normal file
23
src/test/codegen/noalias-flag.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// compile-flags: -O -Zmutable-noalias=no
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
// `-Zmutable-noalias=no` should disable noalias on mut refs...
|
||||||
|
|
||||||
|
// CHECK-LABEL: @test_mut_ref(
|
||||||
|
// CHECK-NOT: noalias
|
||||||
|
// CHECK-SAME: %x
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn test_mut_ref(x: &mut i32) -> &mut i32 {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...but not on shared refs
|
||||||
|
|
||||||
|
// CHECK-LABEL: @test_ref(
|
||||||
|
// CHECK-SAME: noalias
|
||||||
|
// CHECK-SAME: %x
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn test_ref(x: &i32) -> &i32 {
|
||||||
|
x
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user