Skip to content

Commit 1630746

Browse files
committed
rustc_trans: always keep track of the Align in LvalueRef.
1 parent 7c6f242 commit 1630746

File tree

9 files changed

+86
-124
lines changed

9 files changed

+86
-124
lines changed

src/librustc_trans/abi.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use cabi_sparc64;
3030
use cabi_nvptx;
3131
use cabi_nvptx64;
3232
use cabi_hexagon;
33-
use mir::place::{Alignment, PlaceRef};
33+
use mir::place::PlaceRef;
3434
use mir::operand::OperandValue;
3535
use type_::Type;
3636
use type_of::{LayoutLlvmExt, PointerKind};
@@ -561,7 +561,7 @@ impl<'a, 'tcx> ArgType<'tcx> {
561561
}
562562
let ccx = bcx.ccx;
563563
if self.is_indirect() {
564-
OperandValue::Ref(val, Alignment::AbiAligned).store(bcx, dst)
564+
OperandValue::Ref(val, self.layout.align).store(bcx, dst)
565565
} else if let PassMode::Cast(cast) = self.mode {
566566
// FIXME(eddyb): Figure out when the simpler Store is safe, clang
567567
// uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.

src/librustc_trans/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
316316

317317
if src_f.layout.ty == dst_f.layout.ty {
318318
memcpy_ty(bcx, dst_f.llval, src_f.llval, src_f.layout,
319-
(src_f.alignment | dst_f.alignment).non_abi());
319+
Some(src_f.align.min(dst_f.align)));
320320
} else {
321321
coerce_unsized_into(bcx, src_f, dst_f);
322322
}

src/librustc_trans/intrinsic.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use intrinsics::{self, Intrinsic};
1414
use llvm;
1515
use llvm::{ValueRef};
1616
use abi::{Abi, FnType, PassMode};
17-
use mir::place::{PlaceRef, Alignment};
17+
use mir::place::PlaceRef;
1818
use mir::operand::{OperandRef, OperandValue};
1919
use base::*;
2020
use common::*;
@@ -106,7 +106,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
106106
let name = &*tcx.item_name(def_id);
107107

108108
let llret_ty = ccx.layout_of(ret_ty).llvm_type(ccx);
109-
let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, Alignment::AbiAligned);
109+
let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align);
110110

111111
let simple = get_simple_intrinsic(ccx, name);
112112
let llval = match name {
@@ -254,7 +254,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
254254
bcx.volatile_store(b, dst.project_field(bcx, 1).llval);
255255
} else {
256256
let val = if let OperandValue::Ref(ptr, align) = args[1].val {
257-
bcx.load(ptr, align.non_abi())
257+
bcx.load(ptr, Some(align))
258258
} else {
259259
if dst.layout.is_zst() {
260260
return;
@@ -330,9 +330,9 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
330330
let overflow = bcx.zext(bcx.extract_value(pair, 1), Type::bool(ccx));
331331

332332
let dest = result.project_field(bcx, 0);
333-
bcx.store(val, dest.llval, dest.alignment.non_abi());
333+
bcx.store(val, dest.llval, dest.non_abi_align());
334334
let dest = result.project_field(bcx, 1);
335-
bcx.store(overflow, dest.llval, dest.alignment.non_abi());
335+
bcx.store(overflow, dest.llval, dest.non_abi_align());
336336

337337
return;
338338
},
@@ -473,9 +473,9 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
473473
let success = bcx.zext(bcx.extract_value(pair, 1), Type::bool(bcx.ccx));
474474

475475
let dest = result.project_field(bcx, 0);
476-
bcx.store(val, dest.llval, dest.alignment.non_abi());
476+
bcx.store(val, dest.llval, dest.non_abi_align());
477477
let dest = result.project_field(bcx, 1);
478-
bcx.store(success, dest.llval, dest.alignment.non_abi());
478+
bcx.store(success, dest.llval, dest.non_abi_align());
479479
return;
480480
} else {
481481
return invalid_monomorphization(ty);
@@ -544,7 +544,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
544544
let tp_ty = substs.type_at(0);
545545
let dst = args[0].deref(bcx.ccx);
546546
let val = if let OperandValue::Ref(ptr, align) = args[1].val {
547-
bcx.load(ptr, align.non_abi())
547+
bcx.load(ptr, Some(align))
548548
} else {
549549
from_immediate(bcx, args[1].immediate())
550550
};
@@ -677,7 +677,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
677677
for i in 0..elems.len() {
678678
let dest = result.project_field(bcx, i);
679679
let val = bcx.extract_value(val, i as u64);
680-
bcx.store(val, dest.llval, dest.alignment.non_abi());
680+
bcx.store(val, dest.llval, dest.non_abi_align());
681681
}
682682
return;
683683
}

src/librustc_trans/mir/block.rs

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use syntax_pos::Pos;
3131

3232
use super::{MirContext, LocalRef};
3333
use super::constant::Const;
34-
use super::place::{Alignment, PlaceRef};
34+
use super::place::PlaceRef;
3535
use super::operand::OperandRef;
3636
use super::operand::OperandValue::{Pair, Ref, Immediate};
3737

@@ -216,7 +216,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
216216
PassMode::Direct(_) | PassMode::Pair(..) => {
217217
let op = self.trans_consume(&bcx, &mir::Place::Local(mir::RETURN_PLACE));
218218
if let Ref(llval, align) = op.val {
219-
bcx.load(llval, align.non_abi())
219+
bcx.load(llval, Some(align))
220220
} else {
221221
op.immediate_or_packed_pair(&bcx)
222222
}
@@ -228,7 +228,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
228228
LocalRef::Operand(None) => bug!("use of return before def"),
229229
LocalRef::Place(tr_place) => {
230230
OperandRef {
231-
val: Ref(tr_place.llval, tr_place.alignment),
231+
val: Ref(tr_place.llval, tr_place.align),
232232
layout: tr_place.layout
233233
}
234234
}
@@ -240,7 +240,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
240240
scratch.llval
241241
}
242242
Ref(llval, align) => {
243-
assert_eq!(align, Alignment::AbiAligned,
243+
assert_eq!(align.abi(), op.layout.align.abi(),
244244
"return place is unaligned!");
245245
llval
246246
}
@@ -579,7 +579,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
579579
(&mir::Operand::Constant(_), Ref(..)) => {
580580
let tmp = PlaceRef::alloca(&bcx, op.layout, "const");
581581
op.val.store(&bcx, tmp);
582-
op.val = Ref(tmp.llval, tmp.alignment);
582+
op.val = Ref(tmp.llval, tmp.align);
583583
}
584584
_ => {}
585585
}
@@ -639,38 +639,40 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
639639
PassMode::Indirect(_) | PassMode::Cast(_) => {
640640
let scratch = PlaceRef::alloca(bcx, arg.layout, "arg");
641641
op.val.store(bcx, scratch);
642-
(scratch.llval, Alignment::AbiAligned, true)
642+
(scratch.llval, scratch.align, true)
643643
}
644644
_ => {
645-
(op.immediate_or_packed_pair(bcx), Alignment::AbiAligned, false)
645+
(op.immediate_or_packed_pair(bcx), arg.layout.align, false)
646646
}
647647
}
648648
}
649-
Ref(llval, align @ Alignment::Packed(_)) if arg.is_indirect() => {
650-
// `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I
651-
// think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't
652-
// have scary latent bugs around.
653-
654-
let scratch = PlaceRef::alloca(bcx, arg.layout, "arg");
655-
base::memcpy_ty(bcx, scratch.llval, llval, op.layout, align.non_abi());
656-
(scratch.llval, Alignment::AbiAligned, true)
649+
Ref(llval, align) => {
650+
if arg.is_indirect() && align.abi() < arg.layout.align.abi() {
651+
// `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I
652+
// think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't
653+
// have scary latent bugs around.
654+
655+
let scratch = PlaceRef::alloca(bcx, arg.layout, "arg");
656+
base::memcpy_ty(bcx, scratch.llval, llval, op.layout, Some(align));
657+
(scratch.llval, scratch.align, true)
658+
} else {
659+
(llval, align, true)
660+
}
657661
}
658-
Ref(llval, align) => (llval, align, true)
659662
};
660663

661664
if by_ref && !arg.is_indirect() {
662665
// Have to load the argument, maybe while casting it.
663666
if let PassMode::Cast(ty) = arg.mode {
664667
llval = bcx.load(bcx.pointercast(llval, ty.llvm_type(bcx.ccx).ptr_to()),
665-
(align | Alignment::Packed(arg.layout.align))
666-
.non_abi());
668+
Some(align.min(arg.layout.align)));
667669
} else {
668670
// We can't use `PlaceRef::load` here because the argument
669671
// may have a type we don't treat as immediate, but the ABI
670672
// used for this call is passing it by-value. In that case,
671673
// the load would just produce `OperandValue::Ref` instead
672674
// of the `OperandValue::Immediate` we need for the call.
673-
llval = bcx.load(llval, align.non_abi());
675+
llval = bcx.load(llval, Some(align));
674676
if let layout::Abi::Scalar(ref scalar) = arg.layout.abi {
675677
if scalar.is_bool() {
676678
bcx.range_metadata(llval, 0..2);
@@ -820,21 +822,17 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
820822
self.trans_place(bcx, dest)
821823
};
822824
if fn_ret.is_indirect() {
823-
match dest.alignment {
824-
Alignment::AbiAligned => {
825-
llargs.push(dest.llval);
826-
ReturnDest::Nothing
827-
},
828-
Alignment::Packed(_) => {
829-
// Currently, MIR code generation does not create calls
830-
// that store directly to fields of packed structs (in
831-
// fact, the calls it creates write only to temps),
832-
//
833-
// If someone changes that, please update this code path
834-
// to create a temporary.
835-
span_bug!(self.mir.span, "can't directly store to unaligned value");
836-
}
825+
if dest.align.abi() < dest.layout.align.abi() {
826+
// Currently, MIR code generation does not create calls
827+
// that store directly to fields of packed structs (in
828+
// fact, the calls it creates write only to temps),
829+
//
830+
// If someone changes that, please update this code path
831+
// to create a temporary.
832+
span_bug!(self.mir.span, "can't directly store to unaligned value");
837833
}
834+
llargs.push(dest.llval);
835+
ReturnDest::Nothing
838836
} else {
839837
ReturnDest::Store(dest)
840838
}
@@ -874,8 +872,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
874872
let llty = src.layout.llvm_type(bcx.ccx);
875873
let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to());
876874
let align = src.layout.align.min(dst.layout.align);
877-
src.val.store(bcx,
878-
PlaceRef::new_sized(cast_ptr, src.layout, Alignment::Packed(align)));
875+
src.val.store(bcx, PlaceRef::new_sized(cast_ptr, src.layout, align));
879876
}
880877

881878

src/librustc_trans/mir/constant.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ use syntax::ast;
4242
use std::fmt;
4343
use std::ptr;
4444

45-
use super::place::Alignment;
4645
use super::operand::{OperandRef, OperandValue};
4746
use super::MirContext;
4847

@@ -182,12 +181,12 @@ impl<'a, 'tcx> Const<'tcx> {
182181
let align = ccx.align_of(self.ty);
183182
let ptr = consts::addr_of(ccx, self.llval, align, "const");
184183
OperandValue::Ref(consts::ptrcast(ptr, layout.llvm_type(ccx).ptr_to()),
185-
Alignment::AbiAligned)
184+
layout.align)
186185
};
187186

188187
OperandRef {
189188
val,
190-
layout: ccx.layout_of(self.ty)
189+
layout
191190
}
192191
}
193192
}

src/librustc_trans/mir/mod.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
3535
pub use self::constant::trans_static_initializer;
3636

3737
use self::analyze::CleanupKind;
38-
use self::place::{Alignment, PlaceRef};
38+
use self::place::PlaceRef;
3939
use rustc::mir::traversal;
4040

4141
use self::operand::{OperandRef, OperandValue};
@@ -279,9 +279,7 @@ pub fn trans_mir<'a, 'tcx: 'a>(
279279
if local == mir::RETURN_PLACE && mircx.fn_ty.ret.is_indirect() {
280280
debug!("alloc: {:?} (return place) -> place", local);
281281
let llretptr = llvm::get_param(llfn, 0);
282-
LocalRef::Place(PlaceRef::new_sized(llretptr,
283-
layout,
284-
Alignment::AbiAligned))
282+
LocalRef::Place(PlaceRef::new_sized(llretptr, layout, layout.align))
285283
} else if memory_locals.contains(local.index()) {
286284
debug!("alloc: {:?} -> place", local);
287285
LocalRef::Place(PlaceRef::alloca(&bcx, layout, &format!("{:?}", local)))
@@ -474,7 +472,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
474472
let llarg = llvm::get_param(bcx.llfn(), llarg_idx as c_uint);
475473
bcx.set_value_name(llarg, &name);
476474
llarg_idx += 1;
477-
PlaceRef::new_sized(llarg, arg.layout, Alignment::AbiAligned)
475+
PlaceRef::new_sized(llarg, arg.layout, arg.layout.align)
478476
} else {
479477
let tmp = PlaceRef::alloca(bcx, arg.layout, &name);
480478
arg.store_fn_arg(bcx, &mut llarg_idx, tmp);

src/librustc_trans/mir/operand.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use llvm::ValueRef;
1212
use rustc::ty;
13-
use rustc::ty::layout::{self, LayoutOf, TyLayout};
13+
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
1414
use rustc::mir;
1515
use rustc_data_structures::indexed_vec::Idx;
1616

@@ -25,7 +25,7 @@ use std::fmt;
2525
use std::ptr;
2626

2727
use super::{MirContext, LocalRef};
28-
use super::place::{Alignment, PlaceRef};
28+
use super::place::PlaceRef;
2929

3030
/// The representation of a Rust value. The enum variant is in fact
3131
/// uniquely determined by the value's type, but is kept as a
@@ -34,7 +34,7 @@ use super::place::{Alignment, PlaceRef};
3434
pub enum OperandValue {
3535
/// A reference to the actual operand. The data is guaranteed
3636
/// to be valid for the operand's lifetime.
37-
Ref(ValueRef, Alignment),
37+
Ref(ValueRef, Align),
3838
/// A single LLVM value.
3939
Immediate(ValueRef),
4040
/// A pair of immediate LLVM values. Used by fat pointers too.
@@ -107,11 +107,12 @@ impl<'a, 'tcx> OperandRef<'tcx> {
107107
OperandValue::Pair(llptr, llextra) => (llptr, llextra),
108108
OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self)
109109
};
110+
let layout = ccx.layout_of(projected_ty);
110111
PlaceRef {
111112
llval: llptr,
112113
llextra,
113-
layout: ccx.layout_of(projected_ty),
114-
alignment: Alignment::AbiAligned,
114+
layout,
115+
align: layout.align,
115116
}
116117
}
117118

@@ -222,9 +223,9 @@ impl<'a, 'tcx> OperandValue {
222223
match self {
223224
OperandValue::Ref(r, source_align) =>
224225
base::memcpy_ty(bcx, dest.llval, r, dest.layout,
225-
(source_align | dest.alignment).non_abi()),
226+
Some(source_align.min(dest.align))),
226227
OperandValue::Immediate(s) => {
227-
bcx.store(base::from_immediate(bcx, s), dest.llval, dest.alignment.non_abi());
228+
bcx.store(base::from_immediate(bcx, s), dest.llval, dest.non_abi_align());
228229
}
229230
OperandValue::Pair(a, b) => {
230231
for (i, &x) in [a, b].iter().enumerate() {
@@ -233,7 +234,7 @@ impl<'a, 'tcx> OperandValue {
233234
if common::val_ty(x) == Type::i1(bcx.ccx) {
234235
llptr = bcx.pointercast(llptr, Type::i8p(bcx.ccx));
235236
}
236-
bcx.store(base::from_immediate(bcx, x), llptr, dest.alignment.non_abi());
237+
bcx.store(base::from_immediate(bcx, x), llptr, dest.non_abi_align());
237238
}
238239
}
239240
}

0 commit comments

Comments
 (0)