diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 2344cd11f66d3d38e65daa64893e8ab0efed8717..bcad3fbc84134047b62816901cfe8022f457bb72 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1239,8 +1239,8 @@ fn parse_cross_lang_lto(slot: &mut CrossLangLto, v: Option<&str>) -> bool { "print the result of the monomorphization collection pass"), mir_opt_level: usize = (1, parse_uint, [TRACKED], "set the MIR optimization level (0-3, default: 1)"), - mutable_noalias: bool = (false, parse_bool, [TRACKED], - "emit noalias metadata for mutable references"), + mutable_noalias: Option = (None, parse_opt_bool, [TRACKED], + "emit noalias metadata for mutable references (default: yes on LLVM >= 6)"), arg_align_attributes: bool = (false, parse_bool, [TRACKED], "emit align metadata for reference arguments"), dump_mir: Option = (None, parse_opt_string, [UNTRACKED], diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index 5f186e7514ecc54bcba90b11f008705121f123b8..21436b74731f2827eefb5889419a7e92fa1eac59 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -10,6 +10,7 @@ use abi::{FnType, FnTypeExt}; use common::*; +use llvm; use rustc::hir; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout}; @@ -428,8 +429,13 @@ fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) PointerKind::Shared }, hir::MutMutable => { - if cx.tcx.sess.opts.debugging_opts.mutable_noalias || - cx.tcx.sess.panic_strategy() == PanicStrategy::Abort { + // Only emit noalias annotations for LLVM >= 6 or in panic=abort + // mode, as prior versions had many bugs in conjunction with + // unwinding. See also issue #31681. + let mutable_noalias = cx.tcx.sess.opts.debugging_opts.mutable_noalias + .unwrap_or(unsafe { llvm::LLVMRustVersionMajor() >= 6 } + || cx.tcx.sess.panic_strategy() == PanicStrategy::Abort); + if mutable_noalias { PointerKind::UniqueBorrowed } else { PointerKind::Shared diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs index 40a9ea5a181392313fa415910297f5a107a6b39c..e3fa7a7db39a254bd2736fdd8ced347ad4a0157c 100644 --- a/src/test/codegen/function-arguments.rs +++ b/src/test/codegen/function-arguments.rs @@ -10,6 +10,7 @@ // compile-flags: -C no-prepopulate-passes // ignore-tidy-linelength +// min-llvm-version 6.0 #![crate_type = "lib"] #![feature(custom_attribute)] @@ -52,16 +53,14 @@ pub fn named_borrow<'r>(_: &'r i32) { pub fn unsafe_borrow(_: &UnsafeInner) { } -// CHECK: @mutable_unsafe_borrow(i16* dereferenceable(2) %arg0) +// CHECK: @mutable_unsafe_borrow(i16* noalias dereferenceable(2) %arg0) // ... unless this is a mutable borrow, those never alias -// ... except that there's this LLVM bug that forces us to not use noalias, see #29485 #[no_mangle] pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) { } -// CHECK: @mutable_borrow(i32* dereferenceable(4) %arg0) +// CHECK: @mutable_borrow(i32* noalias dereferenceable(4) %arg0) // FIXME #25759 This should also have `nocapture` -// ... there's this LLVM bug that forces us to not use noalias, see #29485 #[no_mangle] pub fn mutable_borrow(_: &mut i32) { } @@ -103,9 +102,8 @@ pub fn helper(_: usize) { pub fn slice(_: &[u8]) { } -// CHECK: @mutable_slice([0 x i8]* nonnull %arg0.0, [[USIZE]] %arg0.1) +// CHECK: @mutable_slice([0 x i8]* noalias nonnull %arg0.0, [[USIZE]] %arg0.1) // FIXME #25759 This should also have `nocapture` -// ... there's this LLVM bug that forces us to not use noalias, see #29485 #[no_mangle] pub fn mutable_slice(_: &mut [u8]) { }