diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index a1532c044e3dc..26af9c9622ffe 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -377,7 +377,13 @@ pub enum MetadataType { MD_prof = 2, MD_fpmath = 3, MD_range = 4, - MD_tbaa_struct = 5 + MD_tbaa_struct = 5, + MD_invariant_load = 6, + MD_alias_scope = 7, + MD_noalias = 8, + MD_nontemporal = 9, + MD_mem_parallel_loop_access = 10, + MD_nonnull = 11, } // Inline Asm Dialect diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 9e561fc883bb0..64cffaf08b4c0 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -1033,6 +1033,8 @@ pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, // for this leads to bad optimizations, so its arg type is an appropriately sized integer // and we have to convert it Load(cx, BitCast(cx, ptr, type_of::arg_type_of(cx.ccx(), t).ptr_to())) + } else if ty::type_is_region_ptr(t) || ty::type_is_unique(t) { + LoadNonNull(cx, ptr) } else if ty::type_is_char(t) { // a char is a Unicode codepoint, and so takes values from 0 // to 0x10FFFF inclusive only. diff --git a/src/librustc_trans/trans/build.rs b/src/librustc_trans/trans/build.rs index 7acac5a12ebd2..c288a8196e63c 100644 --- a/src/librustc_trans/trans/build.rs +++ b/src/librustc_trans/trans/build.rs @@ -629,6 +629,23 @@ pub fn LoadRangeAssert(cx: Block, pointer_val: ValueRef, lo: u64, } } +pub fn LoadNonNull(cx: Block, ptr: ValueRef) -> ValueRef { + if cx.unreachable.get() { + let ccx = cx.fcx.ccx; + let ty = val_ty(ptr); + let eltty = if ty.kind() == llvm::Array { + ty.element_type() + } else { + ccx.int_type() + }; + unsafe { + llvm::LLVMGetUndef(eltty.to_ref()) + } + } else { + B(cx).load_nonnull(ptr) + } +} + pub fn Store(cx: Block, val: ValueRef, ptr: ValueRef) { if cx.unreachable.get() { return; } B(cx).store(val, ptr) diff --git a/src/librustc_trans/trans/builder.rs b/src/librustc_trans/trans/builder.rs index 32e16c7bf8d98..e268c2f0d5cc2 100644 --- a/src/librustc_trans/trans/builder.rs +++ b/src/librustc_trans/trans/builder.rs @@ -22,6 +22,7 @@ use util::nodemap::FnvHashMap; use libc::{c_uint, c_char}; use std::ffi::CString; +use std::ptr; use syntax::codemap::Span; pub struct Builder<'a, 'tcx: 'a> { @@ -498,6 +499,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { value } + pub fn load_nonnull(&self, ptr: ValueRef) -> ValueRef { + let value = self.load(ptr); + unsafe { + llvm::LLVMSetMetadata(value, llvm::MD_nonnull as c_uint, + llvm::LLVMMDNodeInContext(self.ccx.llcx(), ptr::null(), 0)); + } + + value + } + pub fn store(&self, val: ValueRef, ptr: ValueRef) { debug!("Store {} -> {}", self.ccx.tn().val_to_string(val),