From 16307465d5ab0ab0d51f57816a69c8f1eebce199 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 1 Dec 2017 19:16:39 +0200 Subject: [PATCH] rustc_trans: always keep track of the Align in LvalueRef. --- src/librustc_trans/abi.rs | 4 +- src/librustc_trans/base.rs | 2 +- src/librustc_trans/intrinsic.rs | 18 +++---- src/librustc_trans/mir/block.rs | 65 +++++++++++------------ src/librustc_trans/mir/constant.rs | 5 +- src/librustc_trans/mir/mod.rs | 8 ++- src/librustc_trans/mir/operand.rs | 17 +++--- src/librustc_trans/mir/place.rs | 85 +++++++++--------------------- src/librustc_trans/mir/rvalue.rs | 4 +- 9 files changed, 85 insertions(+), 123 deletions(-) diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 29905184001..4190a5bb663 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -30,7 +30,7 @@ use cabi_sparc64; use cabi_nvptx; use cabi_nvptx64; use cabi_hexagon; -use mir::place::{Alignment, PlaceRef}; +use mir::place::PlaceRef; use mir::operand::OperandValue; use type_::Type; use type_of::{LayoutLlvmExt, PointerKind}; @@ -561,7 +561,7 @@ impl<'a, 'tcx> ArgType<'tcx> { } let ccx = bcx.ccx; if self.is_indirect() { - OperandValue::Ref(val, Alignment::AbiAligned).store(bcx, dst) + OperandValue::Ref(val, self.layout.align).store(bcx, dst) } else if let PassMode::Cast(cast) = self.mode { // FIXME(eddyb): Figure out when the simpler Store is safe, clang // uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}. diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index bfc72ff06aa..09d7c7d677a 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -316,7 +316,7 @@ pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, if src_f.layout.ty == dst_f.layout.ty { memcpy_ty(bcx, dst_f.llval, src_f.llval, src_f.layout, - (src_f.alignment | dst_f.alignment).non_abi()); + Some(src_f.align.min(dst_f.align))); } else { coerce_unsized_into(bcx, src_f, dst_f); } diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index a35afb80611..a402fa13692 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -14,7 +14,7 @@ use intrinsics::{self, Intrinsic}; use llvm; use llvm::{ValueRef}; use abi::{Abi, FnType, PassMode}; -use mir::place::{PlaceRef, Alignment}; +use mir::place::PlaceRef; use mir::operand::{OperandRef, OperandValue}; use base::*; use common::*; @@ -106,7 +106,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, let name = &*tcx.item_name(def_id); let llret_ty = ccx.layout_of(ret_ty).llvm_type(ccx); - let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, Alignment::AbiAligned); + let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align); let simple = get_simple_intrinsic(ccx, name); let llval = match name { @@ -254,7 +254,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, bcx.volatile_store(b, dst.project_field(bcx, 1).llval); } else { let val = if let OperandValue::Ref(ptr, align) = args[1].val { - bcx.load(ptr, align.non_abi()) + bcx.load(ptr, Some(align)) } else { if dst.layout.is_zst() { return; @@ -330,9 +330,9 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, let overflow = bcx.zext(bcx.extract_value(pair, 1), Type::bool(ccx)); let dest = result.project_field(bcx, 0); - bcx.store(val, dest.llval, dest.alignment.non_abi()); + bcx.store(val, dest.llval, dest.non_abi_align()); let dest = result.project_field(bcx, 1); - bcx.store(overflow, dest.llval, dest.alignment.non_abi()); + bcx.store(overflow, dest.llval, dest.non_abi_align()); return; }, @@ -473,9 +473,9 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, let success = bcx.zext(bcx.extract_value(pair, 1), Type::bool(bcx.ccx)); let dest = result.project_field(bcx, 0); - bcx.store(val, dest.llval, dest.alignment.non_abi()); + bcx.store(val, dest.llval, dest.non_abi_align()); let dest = result.project_field(bcx, 1); - bcx.store(success, dest.llval, dest.alignment.non_abi()); + bcx.store(success, dest.llval, dest.non_abi_align()); return; } else { return invalid_monomorphization(ty); @@ -544,7 +544,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, let tp_ty = substs.type_at(0); let dst = args[0].deref(bcx.ccx); let val = if let OperandValue::Ref(ptr, align) = args[1].val { - bcx.load(ptr, align.non_abi()) + bcx.load(ptr, Some(align)) } else { from_immediate(bcx, args[1].immediate()) }; @@ -677,7 +677,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, for i in 0..elems.len() { let dest = result.project_field(bcx, i); let val = bcx.extract_value(val, i as u64); - bcx.store(val, dest.llval, dest.alignment.non_abi()); + bcx.store(val, dest.llval, dest.non_abi_align()); } return; } diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index fd3408676db..1d90994c150 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -31,7 +31,7 @@ use syntax_pos::Pos; use super::{MirContext, LocalRef}; use super::constant::Const; -use super::place::{Alignment, PlaceRef}; +use super::place::PlaceRef; use super::operand::OperandRef; use super::operand::OperandValue::{Pair, Ref, Immediate}; @@ -216,7 +216,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { PassMode::Direct(_) | PassMode::Pair(..) => { let op = self.trans_consume(&bcx, &mir::Place::Local(mir::RETURN_PLACE)); if let Ref(llval, align) = op.val { - bcx.load(llval, align.non_abi()) + bcx.load(llval, Some(align)) } else { op.immediate_or_packed_pair(&bcx) } @@ -228,7 +228,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { LocalRef::Operand(None) => bug!("use of return before def"), LocalRef::Place(tr_place) => { OperandRef { - val: Ref(tr_place.llval, tr_place.alignment), + val: Ref(tr_place.llval, tr_place.align), layout: tr_place.layout } } @@ -240,7 +240,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { scratch.llval } Ref(llval, align) => { - assert_eq!(align, Alignment::AbiAligned, + assert_eq!(align.abi(), op.layout.align.abi(), "return place is unaligned!"); llval } @@ -579,7 +579,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { (&mir::Operand::Constant(_), Ref(..)) => { let tmp = PlaceRef::alloca(&bcx, op.layout, "const"); op.val.store(&bcx, tmp); - op.val = Ref(tmp.llval, tmp.alignment); + op.val = Ref(tmp.llval, tmp.align); } _ => {} } @@ -639,38 +639,40 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { PassMode::Indirect(_) | PassMode::Cast(_) => { let scratch = PlaceRef::alloca(bcx, arg.layout, "arg"); op.val.store(bcx, scratch); - (scratch.llval, Alignment::AbiAligned, true) + (scratch.llval, scratch.align, true) } _ => { - (op.immediate_or_packed_pair(bcx), Alignment::AbiAligned, false) + (op.immediate_or_packed_pair(bcx), arg.layout.align, false) } } } - Ref(llval, align @ Alignment::Packed(_)) if arg.is_indirect() => { - // `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I - // think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't - // have scary latent bugs around. + Ref(llval, align) => { + if arg.is_indirect() && align.abi() < arg.layout.align.abi() { + // `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I + // think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't + // have scary latent bugs around. - let scratch = PlaceRef::alloca(bcx, arg.layout, "arg"); - base::memcpy_ty(bcx, scratch.llval, llval, op.layout, align.non_abi()); - (scratch.llval, Alignment::AbiAligned, true) + let scratch = PlaceRef::alloca(bcx, arg.layout, "arg"); + base::memcpy_ty(bcx, scratch.llval, llval, op.layout, Some(align)); + (scratch.llval, scratch.align, true) + } else { + (llval, align, true) + } } - Ref(llval, align) => (llval, align, true) }; if by_ref && !arg.is_indirect() { // Have to load the argument, maybe while casting it. if let PassMode::Cast(ty) = arg.mode { llval = bcx.load(bcx.pointercast(llval, ty.llvm_type(bcx.ccx).ptr_to()), - (align | Alignment::Packed(arg.layout.align)) - .non_abi()); + Some(align.min(arg.layout.align))); } else { // We can't use `PlaceRef::load` here because the argument // may have a type we don't treat as immediate, but the ABI // used for this call is passing it by-value. In that case, // the load would just produce `OperandValue::Ref` instead // of the `OperandValue::Immediate` we need for the call. - llval = bcx.load(llval, align.non_abi()); + llval = bcx.load(llval, Some(align)); if let layout::Abi::Scalar(ref scalar) = arg.layout.abi { if scalar.is_bool() { bcx.range_metadata(llval, 0..2); @@ -820,21 +822,17 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { self.trans_place(bcx, dest) }; if fn_ret.is_indirect() { - match dest.alignment { - Alignment::AbiAligned => { - llargs.push(dest.llval); - ReturnDest::Nothing - }, - Alignment::Packed(_) => { - // Currently, MIR code generation does not create calls - // that store directly to fields of packed structs (in - // fact, the calls it creates write only to temps), - // - // If someone changes that, please update this code path - // to create a temporary. - span_bug!(self.mir.span, "can't directly store to unaligned value"); - } + if dest.align.abi() < dest.layout.align.abi() { + // Currently, MIR code generation does not create calls + // that store directly to fields of packed structs (in + // fact, the calls it creates write only to temps), + // + // If someone changes that, please update this code path + // to create a temporary. + span_bug!(self.mir.span, "can't directly store to unaligned value"); } + llargs.push(dest.llval); + ReturnDest::Nothing } else { ReturnDest::Store(dest) } @@ -874,8 +872,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let llty = src.layout.llvm_type(bcx.ccx); let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to()); let align = src.layout.align.min(dst.layout.align); - src.val.store(bcx, - PlaceRef::new_sized(cast_ptr, src.layout, Alignment::Packed(align))); + src.val.store(bcx, PlaceRef::new_sized(cast_ptr, src.layout, align)); } diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 68913c1d6b7..69105b0cd86 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -42,7 +42,6 @@ use syntax::ast; use std::fmt; use std::ptr; -use super::place::Alignment; use super::operand::{OperandRef, OperandValue}; use super::MirContext; @@ -182,12 +181,12 @@ impl<'a, 'tcx> Const<'tcx> { let align = ccx.align_of(self.ty); let ptr = consts::addr_of(ccx, self.llval, align, "const"); OperandValue::Ref(consts::ptrcast(ptr, layout.llvm_type(ccx).ptr_to()), - Alignment::AbiAligned) + layout.align) }; OperandRef { val, - layout: ccx.layout_of(self.ty) + layout } } } diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index 39e2503081a..2c109e80aee 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -35,7 +35,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx}; pub use self::constant::trans_static_initializer; use self::analyze::CleanupKind; -use self::place::{Alignment, PlaceRef}; +use self::place::PlaceRef; use rustc::mir::traversal; use self::operand::{OperandRef, OperandValue}; @@ -279,9 +279,7 @@ pub fn trans_mir<'a, 'tcx: 'a>( if local == mir::RETURN_PLACE && mircx.fn_ty.ret.is_indirect() { debug!("alloc: {:?} (return place) -> place", local); let llretptr = llvm::get_param(llfn, 0); - LocalRef::Place(PlaceRef::new_sized(llretptr, - layout, - Alignment::AbiAligned)) + LocalRef::Place(PlaceRef::new_sized(llretptr, layout, layout.align)) } else if memory_locals.contains(local.index()) { debug!("alloc: {:?} -> place", local); LocalRef::Place(PlaceRef::alloca(&bcx, layout, &format!("{:?}", local))) @@ -474,7 +472,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, let llarg = llvm::get_param(bcx.llfn(), llarg_idx as c_uint); bcx.set_value_name(llarg, &name); llarg_idx += 1; - PlaceRef::new_sized(llarg, arg.layout, Alignment::AbiAligned) + PlaceRef::new_sized(llarg, arg.layout, arg.layout.align) } else { let tmp = PlaceRef::alloca(bcx, arg.layout, &name); arg.store_fn_arg(bcx, &mut llarg_idx, tmp); diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs index 38817817552..74622cdf582 100644 --- a/src/librustc_trans/mir/operand.rs +++ b/src/librustc_trans/mir/operand.rs @@ -10,7 +10,7 @@ use llvm::ValueRef; use rustc::ty; -use rustc::ty::layout::{self, LayoutOf, TyLayout}; +use rustc::ty::layout::{self, Align, LayoutOf, TyLayout}; use rustc::mir; use rustc_data_structures::indexed_vec::Idx; @@ -25,7 +25,7 @@ use std::fmt; use std::ptr; use super::{MirContext, LocalRef}; -use super::place::{Alignment, PlaceRef}; +use super::place::PlaceRef; /// The representation of a Rust value. The enum variant is in fact /// uniquely determined by the value's type, but is kept as a @@ -34,7 +34,7 @@ use super::place::{Alignment, PlaceRef}; pub enum OperandValue { /// A reference to the actual operand. The data is guaranteed /// to be valid for the operand's lifetime. - Ref(ValueRef, Alignment), + Ref(ValueRef, Align), /// A single LLVM value. Immediate(ValueRef), /// A pair of immediate LLVM values. Used by fat pointers too. @@ -107,11 +107,12 @@ impl<'a, 'tcx> OperandRef<'tcx> { OperandValue::Pair(llptr, llextra) => (llptr, llextra), OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self) }; + let layout = ccx.layout_of(projected_ty); PlaceRef { llval: llptr, llextra, - layout: ccx.layout_of(projected_ty), - alignment: Alignment::AbiAligned, + layout, + align: layout.align, } } @@ -222,9 +223,9 @@ impl<'a, 'tcx> OperandValue { match self { OperandValue::Ref(r, source_align) => base::memcpy_ty(bcx, dest.llval, r, dest.layout, - (source_align | dest.alignment).non_abi()), + Some(source_align.min(dest.align))), OperandValue::Immediate(s) => { - bcx.store(base::from_immediate(bcx, s), dest.llval, dest.alignment.non_abi()); + bcx.store(base::from_immediate(bcx, s), dest.llval, dest.non_abi_align()); } OperandValue::Pair(a, b) => { for (i, &x) in [a, b].iter().enumerate() { @@ -233,7 +234,7 @@ impl<'a, 'tcx> OperandValue { if common::val_ty(x) == Type::i1(bcx.ccx) { llptr = bcx.pointercast(llptr, Type::i8p(bcx.ccx)); } - bcx.store(base::from_immediate(bcx, x), llptr, dest.alignment.non_abi()); + bcx.store(base::from_immediate(bcx, x), llptr, dest.non_abi_align()); } } } diff --git a/src/librustc_trans/mir/place.rs b/src/librustc_trans/mir/place.rs index 214686f4ca1..c217f2e8994 100644 --- a/src/librustc_trans/mir/place.rs +++ b/src/librustc_trans/mir/place.rs @@ -24,50 +24,10 @@ use value::Value; use glue; use std::ptr; -use std::ops; use super::{MirContext, LocalRef}; use super::operand::{OperandRef, OperandValue}; -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Alignment { - Packed(Align), - AbiAligned, -} - -impl ops::BitOr for Alignment { - type Output = Self; - - fn bitor(self, rhs: Self) -> Self { - match (self, rhs) { - (Alignment::Packed(a), Alignment::Packed(b)) => { - Alignment::Packed(a.min(b)) - } - (Alignment::Packed(x), _) | (_, Alignment::Packed(x)) => { - Alignment::Packed(x) - } - (Alignment::AbiAligned, Alignment::AbiAligned) => { - Alignment::AbiAligned - } - } - } -} - -impl<'a> From> for Alignment { - fn from(layout: TyLayout) -> Self { - Alignment::Packed(layout.align) - } -} - -impl Alignment { - pub fn non_abi(self) -> Option { - match self { - Alignment::Packed(x) => Some(x), - Alignment::AbiAligned => None, - } - } -} - #[derive(Copy, Clone, Debug)] pub struct PlaceRef<'tcx> { /// Pointer to the contents of the place @@ -79,20 +39,20 @@ pub struct PlaceRef<'tcx> { /// Monomorphized type of this place, including variant information pub layout: TyLayout<'tcx>, - /// Whether this place is known to be aligned according to its layout - pub alignment: Alignment, + /// What alignment we know for this place + pub align: Align, } impl<'a, 'tcx> PlaceRef<'tcx> { pub fn new_sized(llval: ValueRef, layout: TyLayout<'tcx>, - alignment: Alignment) + align: Align) -> PlaceRef<'tcx> { PlaceRef { llval, llextra: ptr::null_mut(), layout, - alignment + align } } @@ -100,7 +60,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { -> PlaceRef<'tcx> { debug!("alloca({:?}: {:?})", name, layout); let tmp = bcx.alloca(layout.llvm_type(bcx.ccx), name, layout.align); - Self::new_sized(tmp, layout, Alignment::AbiAligned) + Self::new_sized(tmp, layout, layout.align) } pub fn len(&self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef { @@ -121,6 +81,14 @@ impl<'a, 'tcx> PlaceRef<'tcx> { !self.llextra.is_null() } + pub fn non_abi_align(self) -> Option { + if self.align.abi() >= self.layout.align.abi() { + None + } else { + Some(self.align) + } + } + pub fn load(&self, bcx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> { debug!("PlaceRef::load: {:?}", self); @@ -167,7 +135,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { let llval = if !const_llval.is_null() { const_llval } else { - let load = bcx.load(self.llval, self.alignment.non_abi()); + let load = bcx.load(self.llval, self.non_abi_align()); if let layout::Abi::Scalar(ref scalar) = self.layout.abi { scalar_load_metadata(load, scalar); } @@ -181,7 +149,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { if scalar.is_bool() { llptr = bcx.pointercast(llptr, Type::i8p(bcx.ccx)); } - let load = bcx.load(llptr, self.alignment.non_abi()); + let load = bcx.load(llptr, self.non_abi_align()); scalar_load_metadata(load, scalar); if scalar.is_bool() { bcx.trunc(load, Type::i1(bcx.ccx)) @@ -191,7 +159,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { }; OperandValue::Pair(load(0, a), load(1, b)) } else { - OperandValue::Ref(self.llval, self.alignment) + OperandValue::Ref(self.llval, self.align) }; OperandRef { val, layout: self.layout } @@ -202,7 +170,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { let ccx = bcx.ccx; let field = self.layout.field(ccx, ix); let offset = self.layout.fields.offset(ix); - let alignment = self.alignment | Alignment::from(self.layout); + let align = self.align.min(self.layout.align).min(field.align); let simple = || { // Unions and newtypes only use an offset of 0. @@ -224,7 +192,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { ptr::null_mut() }, layout: field, - alignment, + align, } }; @@ -271,7 +239,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { let unaligned_offset = C_usize(ccx, offset.bytes()); // Get the alignment of the field - let (_, align) = glue::size_and_align_of_dst(bcx, field.ty, meta); + let (_, unsized_align) = glue::size_and_align_of_dst(bcx, field.ty, meta); // Bump the unaligned offset up to the appropriate alignment using the // following expression: @@ -279,9 +247,9 @@ impl<'a, 'tcx> PlaceRef<'tcx> { // (unaligned offset + (align - 1)) & -align // Calculate offset - let align_sub_1 = bcx.sub(align, C_usize(ccx, 1u64)); + let align_sub_1 = bcx.sub(unsized_align, C_usize(ccx, 1u64)); let offset = bcx.and(bcx.add(unaligned_offset, align_sub_1), - bcx.neg(align)); + bcx.neg(unsized_align)); debug!("struct_field_ptr: DST field offset: {:?}", Value(offset)); @@ -297,7 +265,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { llval: bcx.pointercast(byte_ptr, ll_fty.ptr_to()), llextra: self.llextra, layout: field, - alignment, + align, } } @@ -370,7 +338,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { .discriminant_for_variant(bcx.tcx(), variant_index) .to_u128_unchecked() as u64; bcx.store(C_int(ptr.layout.llvm_type(bcx.ccx), to as i64), - ptr.llval, ptr.alignment.non_abi()); + ptr.llval, ptr.non_abi_align()); } layout::Variants::NicheFilling { dataful_variant, @@ -414,7 +382,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { llval: bcx.inbounds_gep(self.llval, &[C_usize(bcx.ccx, 0), llindex]), llextra: ptr::null_mut(), layout: self.layout.field(bcx.ccx, 0), - alignment: self.alignment + align: self.align } } @@ -463,9 +431,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let result = match *place { mir::Place::Local(_) => bug!(), // handled above mir::Place::Static(box mir::Static { def_id, ty }) => { - PlaceRef::new_sized(consts::get_static(ccx, def_id), - ccx.layout_of(self.monomorphize(&ty)), - Alignment::AbiAligned) + let layout = ccx.layout_of(self.monomorphize(&ty)); + PlaceRef::new_sized(consts::get_static(ccx, def_id), layout, layout.align) }, mir::Place::Projection(box mir::Projection { ref base, diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index a93c0cea118..577715797ad 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -104,7 +104,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let start = dest.project_index(&bcx, C_usize(bcx.ccx, 0)).llval; if let OperandValue::Immediate(v) = tr_elem.val { - let align = dest.alignment.non_abi() + let align = dest.non_abi_align() .unwrap_or(tr_elem.layout.align); let align = C_i32(bcx.ccx, align.abi() as i32); let size = C_usize(bcx.ccx, dest.layout.size.bytes()); @@ -139,7 +139,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { header_bcx.cond_br(keep_going, body_bcx.llbb(), next_bcx.llbb()); tr_elem.val.store(&body_bcx, - PlaceRef::new_sized(current, tr_elem.layout, dest.alignment)); + PlaceRef::new_sized(current, tr_elem.layout, dest.align)); let next = body_bcx.inbounds_gep(current, &[C_usize(bcx.ccx, 1)]); body_bcx.br(header_bcx.llbb());