Skip to content

Commit 7d115c9

Browse files
committed
add an intrinsic for inbounds GEP
1 parent f23fb19 commit 7d115c9

File tree

5 files changed

+53
-2
lines changed

5 files changed

+53
-2
lines changed

src/librustc/middle/trans/foreign.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,11 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
888888
let offset = get_param(decl, first_real_arg + 1);
889889
Ret(bcx, GEP(bcx, ptr, [offset]));
890890
}
891+
"offset_inbounds" => {
892+
let ptr = get_param(decl, first_real_arg);
893+
let offset = get_param(decl, first_real_arg + 1);
894+
Ret(bcx, InBoundsGEP(bcx, ptr, [offset]));
895+
}
891896
"memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32),
892897
"memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64),
893898
"memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32),

src/librustc/middle/trans/type_use.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
148148
"visit_tydesc" | "forget" | "frame_address" |
149149
"morestack_addr" => 0,
150150

151-
"offset" | "memcpy32" | "memcpy64" | "memmove32" | "memmove64" |
151+
"offset" | "offset_inbounds" |
152+
"memcpy32" | "memcpy64" | "memmove32" | "memmove64" |
152153
"memset32" | "memset64" => use_repr,
153154

154155
"sqrtf32" | "sqrtf64" | "powif32" | "powif64" |

src/librustc/middle/typeck/check/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3481,6 +3481,20 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
34813481
mutbl: ast::m_imm
34823482
}))
34833483
}
3484+
"offset_inbounds" => {
3485+
(1,
3486+
~[
3487+
ty::mk_ptr(tcx, ty::mt {
3488+
ty: param(ccx, 0),
3489+
mutbl: ast::m_imm
3490+
}),
3491+
ty::mk_int()
3492+
],
3493+
ty::mk_ptr(tcx, ty::mt {
3494+
ty: param(ccx, 0),
3495+
mutbl: ast::m_imm
3496+
}))
3497+
}
34843498
"memcpy32" => {
34853499
(1,
34863500
~[

src/libstd/ptr.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ pub trait RawPtr<T> {
272272
fn is_not_null(&self) -> bool;
273273
unsafe fn to_option(&self) -> Option<&T>;
274274
fn offset(&self, count: int) -> Self;
275+
#[cfg(not(stage0))]
276+
unsafe fn offset_inbounds(self, count: int) -> Self;
275277
}
276278

277279
/// Extension methods for immutable pointers
@@ -304,6 +306,14 @@ impl<T> RawPtr<T> for *T {
304306
/// Calculates the offset from a pointer.
305307
#[inline]
306308
fn offset(&self, count: int) -> *T { offset(*self, count) }
309+
310+
/// Calculates the offset from a pointer. The offset *must* be in-bounds of
311+
/// the object, or one-byte-past-the-end.
312+
#[inline]
313+
#[cfg(not(stage0))]
314+
unsafe fn offset_inbounds(self, count: int) -> *T {
315+
intrinsics::offset_inbounds(self, count)
316+
}
307317
}
308318

309319
/// Extension methods for mutable pointers
@@ -336,6 +346,18 @@ impl<T> RawPtr<T> for *mut T {
336346
/// Calculates the offset from a mutable pointer.
337347
#[inline]
338348
fn offset(&self, count: int) -> *mut T { mut_offset(*self, count) }
349+
350+
/// Calculates the offset from a pointer. The offset *must* be in-bounds of
351+
/// the object, or one-byte-past-the-end. An arithmetic overflow is also
352+
/// undefined behaviour.
353+
///
354+
/// This method should be preferred over `offset` when the guarantee can be
355+
/// satisfied, to enable better optimization.
356+
#[inline]
357+
#[cfg(not(stage0))]
358+
unsafe fn offset_inbounds(self, count: int) -> *mut T {
359+
intrinsics::offset_inbounds(self as *T, count) as *mut T
360+
}
339361
}
340362

341363
// Equality for pointers

src/libstd/unstable/intrinsics.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,12 +317,21 @@ extern "rust-intrinsic" {
317317
/// Get the address of the `__morestack` stack growth function.
318318
pub fn morestack_addr() -> *();
319319

320-
/// Adjust a pointer by an offset.
320+
/// Calculates the offset from a pointer.
321321
///
322322
/// This is implemented as an intrinsic to avoid converting to and from an
323323
/// integer, since the conversion would throw away aliasing information.
324324
pub fn offset<T>(dst: *T, offset: int) -> *T;
325325

326+
/// Calculates the offset from a pointer. The offset *must* be in-bounds of
327+
/// the object, or one-byte-past-the-end. An arithmetic overflow is also
328+
/// undefined behaviour.
329+
///
330+
/// This intrinsic should be preferred over `offset` when the guarantee can
331+
/// be satisfied, to enable better optimization.
332+
#[cfg(not(stage0))]
333+
pub fn offset_inbounds<T>(dst: *T, offset: int) -> *T;
334+
326335
/// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of
327336
/// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
328337
pub fn memcpy32<T>(dst: *mut T, src: *T, count: u32);

0 commit comments

Comments
 (0)