Skip to content

Commit ba2f13e

Browse files
committed
Auto merge of rust-lang#21885 - dotdash:nonnull_load, r=alexcrichton
These pointers are never null, let's tell LLVM about it.
2 parents 3ae76d5 + 1a56a1a commit ba2f13e

File tree

4 files changed

+37
-1
lines changed

4 files changed

+37
-1
lines changed

src/librustc_llvm/lib.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,13 @@ pub enum MetadataType {
377377
MD_prof = 2,
378378
MD_fpmath = 3,
379379
MD_range = 4,
380-
MD_tbaa_struct = 5
380+
MD_tbaa_struct = 5,
381+
MD_invariant_load = 6,
382+
MD_alias_scope = 7,
383+
MD_noalias = 8,
384+
MD_nontemporal = 9,
385+
MD_mem_parallel_loop_access = 10,
386+
MD_nonnull = 11,
381387
}
382388

383389
// Inline Asm Dialect

src/librustc_trans/trans/base.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,8 @@ pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
10331033
// for this leads to bad optimizations, so its arg type is an appropriately sized integer
10341034
// and we have to convert it
10351035
Load(cx, BitCast(cx, ptr, type_of::arg_type_of(cx.ccx(), t).ptr_to()))
1036+
} else if ty::type_is_region_ptr(t) || ty::type_is_unique(t) {
1037+
LoadNonNull(cx, ptr)
10361038
} else if ty::type_is_char(t) {
10371039
// a char is a Unicode codepoint, and so takes values from 0
10381040
// to 0x10FFFF inclusive only.

src/librustc_trans/trans/build.rs

+17
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,23 @@ pub fn LoadRangeAssert(cx: Block, pointer_val: ValueRef, lo: u64,
629629
}
630630
}
631631

632+
pub fn LoadNonNull(cx: Block, ptr: ValueRef) -> ValueRef {
633+
if cx.unreachable.get() {
634+
let ccx = cx.fcx.ccx;
635+
let ty = val_ty(ptr);
636+
let eltty = if ty.kind() == llvm::Array {
637+
ty.element_type()
638+
} else {
639+
ccx.int_type()
640+
};
641+
unsafe {
642+
llvm::LLVMGetUndef(eltty.to_ref())
643+
}
644+
} else {
645+
B(cx).load_nonnull(ptr)
646+
}
647+
}
648+
632649
pub fn Store(cx: Block, val: ValueRef, ptr: ValueRef) {
633650
if cx.unreachable.get() { return; }
634651
B(cx).store(val, ptr)

src/librustc_trans/trans/builder.rs

+11
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use util::nodemap::FnvHashMap;
2222
use libc::{c_uint, c_char};
2323

2424
use std::ffi::CString;
25+
use std::ptr;
2526
use syntax::codemap::Span;
2627

2728
pub struct Builder<'a, 'tcx: 'a> {
@@ -498,6 +499,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
498499
value
499500
}
500501

502+
pub fn load_nonnull(&self, ptr: ValueRef) -> ValueRef {
503+
let value = self.load(ptr);
504+
unsafe {
505+
llvm::LLVMSetMetadata(value, llvm::MD_nonnull as c_uint,
506+
llvm::LLVMMDNodeInContext(self.ccx.llcx(), ptr::null(), 0));
507+
}
508+
509+
value
510+
}
511+
501512
pub fn store(&self, val: ValueRef, ptr: ValueRef) {
502513
debug!("Store {} -> {}",
503514
self.ccx.tn().val_to_string(val),

0 commit comments

Comments
 (0)