diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index f14ea279c2d..5fa0ade6055 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -52,7 +52,7 @@ use middle::trans::foreign; use middle::trans::glue; use middle::trans::inline; use middle::trans::machine; -use middle::trans::machine::llsize_of; +use middle::trans::machine::{llalign_of_min, llsize_of}; use middle::trans::meth; use middle::trans::monomorphize; use middle::trans::reachable; @@ -1442,12 +1442,7 @@ pub fn with_cond(bcx: block, val: ValueRef, f: &fn(block) -> block) -> block { next_cx } -pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, - n_bytes: ValueRef) { - // FIXME (Related to #1645, I think?): Provide LLVM with better - // alignment information when the alignment is statically known (it must - // be nothing more than a constant int, or LLVM complains -- not even a - // constant element of a tydesc works). +pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) { let _icx = cx.insn_ctxt("call_memcpy"); let ccx = cx.ccx(); let key = match ccx.sess.targ_cfg.arch { @@ -1462,7 +1457,7 @@ pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, let src_ptr = PointerCast(cx, src, T_ptr(T_i8())); let dst_ptr = PointerCast(cx, dst, T_ptr(T_i8())); let size = IntCast(cx, n_bytes, ccx.int_type); - let align = C_i32(1i32); + let align = C_i32(align as i32); let volatile = C_i1(false); Call(cx, memcpy, [dst_ptr, src_ptr, size, align, volatile]); } @@ -1471,8 +1466,10 @@ pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) { let _icx = bcx.insn_ctxt("memcpy_ty"); let ccx = bcx.ccx(); if ty::type_is_structural(t) { - let llsz = llsize_of(ccx, type_of::type_of(ccx, t)); - call_memcpy(bcx, dst, src, llsz); + let llty = type_of::type_of(ccx, t); + let llsz = llsize_of(ccx, llty); + let llalign = llalign_of_min(ccx, llty); + call_memcpy(bcx, dst, src, llsz, llalign as u32); } else { Store(bcx, Load(bcx, src), dst); } diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 57df27ef199..335dd47b78b 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -521,7 +521,7 @@ pub fn make_opaque_cbox_take_glue( [opaque_tydesc, sz], expr::SaveIn(rval)); let cbox_out = PointerCast(bcx, Load(bcx, rval), llopaquecboxty); - call_memcpy(bcx, cbox_out, cbox_in, sz); + call_memcpy(bcx, cbox_out, cbox_in, sz, 1); Store(bcx, cbox_out, cboxptr); // Take the (deeply cloned) type descriptor diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 7bfec9c89cb..ff17dd82687 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -787,7 +787,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, let llsrcptr = PointerCast(bcx, llsrcptr, T_ptr(T_i8())); let llsize = llsize_of(ccx, llintype); - call_memcpy(bcx, lldestptr, llsrcptr, llsize); + call_memcpy(bcx, lldestptr, llsrcptr, llsize, 1); } } ~"needs_drop" => { diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 29e026189db..278a7355892 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -125,7 +125,7 @@ pub fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> Result { let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr)); let new_data_ptr = get_dataptr(bcx, get_bodyptr(bcx, newptr)); - base::call_memcpy(bcx, new_data_ptr, data_ptr, fill); + base::call_memcpy(bcx, new_data_ptr, data_ptr, fill, 1); let bcx = if ty::type_needs_drop(bcx.tcx(), unit_ty) { iter_vec_raw(bcx, new_data_ptr, vec_ty, fill, glue::take_ty) @@ -370,7 +370,7 @@ pub fn write_content(bcx: block, let bytes = s.len() + 1; // copy null-terminator too let llbytes = C_uint(bcx.ccx(), bytes); let llcstr = C_cstr(bcx.ccx(), s); - base::call_memcpy(bcx, lldest, llcstr, llbytes); + base::call_memcpy(bcx, lldest, llcstr, llbytes, 1); return bcx; } }