Skip to content

Commit 5cab0bf

Browse files
committed
rustc_trans: always require alignment for load/store/memcpy.
1 parent 1630746 commit 5cab0bf

File tree

10 files changed

+56
-61
lines changed

10 files changed

+56
-61
lines changed

src/librustc_trans/abi.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ impl<'a, 'tcx> ArgType<'tcx> {
568568
let can_store_through_cast_ptr = false;
569569
if can_store_through_cast_ptr {
570570
let cast_dst = bcx.pointercast(dst.llval, cast.llvm_type(ccx).ptr_to());
571-
bcx.store(val, cast_dst, Some(self.layout.align));
571+
bcx.store(val, cast_dst, self.layout.align);
572572
} else {
573573
// The actual return type is a struct, but the ABI
574574
// adaptation code has cast it into some scalar type. The
@@ -585,19 +585,20 @@ impl<'a, 'tcx> ArgType<'tcx> {
585585
// bitcasting to the struct type yields invalid cast errors.
586586

587587
// We instead thus allocate some scratch space...
588-
let llscratch = bcx.alloca(cast.llvm_type(ccx), "abi_cast", cast.align(ccx));
589588
let scratch_size = cast.size(ccx);
589+
let scratch_align = cast.align(ccx);
590+
let llscratch = bcx.alloca(cast.llvm_type(ccx), "abi_cast", scratch_align);
590591
bcx.lifetime_start(llscratch, scratch_size);
591592

592593
// ...where we first store the value...
593-
bcx.store(val, llscratch, None);
594+
bcx.store(val, llscratch, scratch_align);
594595

595596
// ...and then memcpy it to the intended destination.
596597
base::call_memcpy(bcx,
597598
bcx.pointercast(dst.llval, Type::i8p(ccx)),
598599
bcx.pointercast(llscratch, Type::i8p(ccx)),
599600
C_usize(ccx, self.layout.size.bytes()),
600-
self.layout.align.min(cast.align(ccx)));
601+
self.layout.align.min(scratch_align));
601602

602603
bcx.lifetime_end(llscratch, scratch_size);
603604
}

src/librustc_trans/base.rs

Lines changed: 2 additions & 3 deletions
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-
Some(src_f.align.min(dst_f.align)));
319+
src_f.align.min(dst_f.align));
320320
} else {
321321
coerce_unsized_into(bcx, src_f, dst_f);
322322
}
@@ -430,14 +430,13 @@ pub fn memcpy_ty<'a, 'tcx>(
430430
dst: ValueRef,
431431
src: ValueRef,
432432
layout: TyLayout<'tcx>,
433-
align: Option<Align>,
433+
align: Align,
434434
) {
435435
let size = layout.size.bytes();
436436
if size == 0 {
437437
return;
438438
}
439439

440-
let align = align.unwrap_or(layout.align);
441440
call_memcpy(bcx, dst, src, C_usize(bcx.ccx, size), align);
442441
}
443442

src/librustc_trans/builder.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -518,13 +518,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
518518
}
519519
}
520520

521-
pub fn load(&self, ptr: ValueRef, align: Option<Align>) -> ValueRef {
521+
pub fn load(&self, ptr: ValueRef, align: Align) -> ValueRef {
522522
self.count_insn("load");
523523
unsafe {
524524
let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname());
525-
if let Some(align) = align {
526-
llvm::LLVMSetAlignment(load, align.abi() as c_uint);
527-
}
525+
llvm::LLVMSetAlignment(load, align.abi() as c_uint);
528526
load
529527
}
530528
}
@@ -573,16 +571,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
573571
}
574572
}
575573

576-
pub fn store(&self, val: ValueRef, ptr: ValueRef, align: Option<Align>) -> ValueRef {
574+
pub fn store(&self, val: ValueRef, ptr: ValueRef, align: Align) -> ValueRef {
577575
debug!("Store {:?} -> {:?}", Value(val), Value(ptr));
578576
assert!(!self.llbuilder.is_null());
579577
self.count_insn("store");
580578
let ptr = self.check_store(val, ptr);
581579
unsafe {
582580
let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
583-
if let Some(align) = align {
584-
llvm::LLVMSetAlignment(store, align.abi() as c_uint);
585-
}
581+
llvm::LLVMSetAlignment(store, align.abi() as c_uint);
586582
store
587583
}
588584
}

src/librustc_trans/intrinsic.rs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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, Some(align))
257+
bcx.load(ptr, 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.non_abi_align());
333+
bcx.store(val, dest.llval, dest.align);
334334
let dest = result.project_field(bcx, 1);
335-
bcx.store(overflow, dest.llval, dest.non_abi_align());
335+
bcx.store(overflow, dest.llval, dest.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.non_abi_align());
476+
bcx.store(val, dest.llval, dest.align);
477477
let dest = result.project_field(bcx, 1);
478-
bcx.store(success, dest.llval, dest.non_abi_align());
478+
bcx.store(success, dest.llval, dest.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, Some(align))
547+
bcx.load(ptr, 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.non_abi_align());
680+
bcx.store(val, dest.llval, dest.align);
681681
}
682682
return;
683683
}
@@ -688,8 +688,8 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
688688

689689
if !fn_ty.ret.is_ignore() {
690690
if let PassMode::Cast(ty) = fn_ty.ret.mode {
691-
let ptr = bcx.pointercast(llresult, ty.llvm_type(ccx).ptr_to());
692-
bcx.store(llval, ptr, Some(ccx.align_of(ret_ty)));
691+
let ptr = bcx.pointercast(result.llval, ty.llvm_type(ccx).ptr_to());
692+
bcx.store(llval, ptr, result.align);
693693
} else {
694694
OperandRef::from_immediate_or_packed_pair(bcx, llval, result.layout)
695695
.val.store(bcx, result);
@@ -758,7 +758,8 @@ fn try_intrinsic<'a, 'tcx>(
758758
) {
759759
if bcx.sess().no_landing_pads() {
760760
bcx.call(func, &[data], None);
761-
bcx.store(C_null(Type::i8p(&bcx.ccx)), dest, None);
761+
let ptr_align = bcx.tcx().data_layout.pointer_align;
762+
bcx.store(C_null(Type::i8p(&bcx.ccx)), dest, ptr_align);
762763
} else if wants_msvc_seh(bcx.sess()) {
763764
trans_msvc_try(bcx, ccx, func, data, local_ptr, dest);
764765
} else {
@@ -833,7 +834,8 @@ fn trans_msvc_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
833834
//
834835
// More information can be found in libstd's seh.rs implementation.
835836
let i64p = Type::i64(ccx).ptr_to();
836-
let slot = bcx.alloca(i64p, "slot", ccx.data_layout().pointer_align);
837+
let ptr_align = bcx.tcx().data_layout.pointer_align;
838+
let slot = bcx.alloca(i64p, "slot", ptr_align);
837839
bcx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(),
838840
None);
839841

@@ -848,13 +850,15 @@ fn trans_msvc_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
848850
None => bug!("msvc_try_filter not defined"),
849851
};
850852
let tok = catchpad.catch_pad(cs, &[tydesc, C_i32(ccx, 0), slot]);
851-
let addr = catchpad.load(slot, None);
852-
let arg1 = catchpad.load(addr, None);
853+
let addr = catchpad.load(slot, ptr_align);
854+
855+
let i64_align = bcx.tcx().data_layout.i64_align;
856+
let arg1 = catchpad.load(addr, i64_align);
853857
let val1 = C_i32(ccx, 1);
854-
let arg2 = catchpad.load(catchpad.inbounds_gep(addr, &[val1]), None);
858+
let arg2 = catchpad.load(catchpad.inbounds_gep(addr, &[val1]), i64_align);
855859
let local_ptr = catchpad.bitcast(local_ptr, i64p);
856-
catchpad.store(arg1, local_ptr, None);
857-
catchpad.store(arg2, catchpad.inbounds_gep(local_ptr, &[val1]), None);
860+
catchpad.store(arg1, local_ptr, i64_align);
861+
catchpad.store(arg2, catchpad.inbounds_gep(local_ptr, &[val1]), i64_align);
858862
catchpad.catch_ret(tok, caught.llbb());
859863

860864
caught.ret(C_i32(ccx, 1));
@@ -863,7 +867,8 @@ fn trans_msvc_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
863867
// Note that no invoke is used here because by definition this function
864868
// can't panic (that's what it's catching).
865869
let ret = bcx.call(llfn, &[func, data, local_ptr], None);
866-
bcx.store(ret, dest, None);
870+
let i32_align = bcx.tcx().data_layout.i32_align;
871+
bcx.store(ret, dest, i32_align);
867872
}
868873

869874
// Definition of the standard "try" function for Rust using the GNU-like model
@@ -923,14 +928,16 @@ fn trans_gnu_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
923928
let vals = catch.landing_pad(lpad_ty, bcx.ccx.eh_personality(), 1, catch.llfn());
924929
catch.add_clause(vals, C_null(Type::i8p(ccx)));
925930
let ptr = catch.extract_value(vals, 0);
926-
catch.store(ptr, catch.bitcast(local_ptr, Type::i8p(ccx).ptr_to()), None);
931+
let ptr_align = bcx.tcx().data_layout.pointer_align;
932+
catch.store(ptr, catch.bitcast(local_ptr, Type::i8p(ccx).ptr_to()), ptr_align);
927933
catch.ret(C_i32(ccx, 1));
928934
});
929935

930936
// Note that no invoke is used here because by definition this function
931937
// can't panic (that's what it's catching).
932938
let ret = bcx.call(llfn, &[func, data, local_ptr], None);
933-
bcx.store(ret, dest, None);
939+
let i32_align = bcx.tcx().data_layout.i32_align;
940+
bcx.store(ret, dest, i32_align);
934941
}
935942

936943
// Helper function to give a Block to a closure to translate a shim function.

src/librustc_trans/meth.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ impl<'a, 'tcx> VirtualIndex {
4040
debug!("get_fn({:?}, {:?})", Value(llvtable), self);
4141

4242
let llvtable = bcx.pointercast(llvtable, fn_ty.llvm_type(bcx.ccx).ptr_to().ptr_to());
43-
let ptr = bcx.load(bcx.inbounds_gep(llvtable, &[C_usize(bcx.ccx, self.0)]), None);
43+
let ptr_align = bcx.tcx().data_layout.pointer_align;
44+
let ptr = bcx.load(bcx.inbounds_gep(llvtable, &[C_usize(bcx.ccx, self.0)]), ptr_align);
4445
bcx.nonnull_metadata(ptr);
4546
// Vtable loads are invariant
4647
bcx.set_invariant_load(ptr);
@@ -52,7 +53,8 @@ impl<'a, 'tcx> VirtualIndex {
5253
debug!("get_int({:?}, {:?})", Value(llvtable), self);
5354

5455
let llvtable = bcx.pointercast(llvtable, Type::isize(bcx.ccx).ptr_to());
55-
let ptr = bcx.load(bcx.inbounds_gep(llvtable, &[C_usize(bcx.ccx, self.0)]), None);
56+
let usize_align = bcx.tcx().data_layout.pointer_align;
57+
let ptr = bcx.load(bcx.inbounds_gep(llvtable, &[C_usize(bcx.ccx, self.0)]), usize_align);
5658
// Vtable loads are invariant
5759
bcx.set_invariant_load(ptr);
5860
ptr

src/librustc_trans/mir/block.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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, Some(align))
219+
bcx.load(llval, align)
220220
} else {
221221
op.immediate_or_packed_pair(&bcx)
222222
}
@@ -247,7 +247,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
247247
};
248248
bcx.load(
249249
bcx.pointercast(llslot, cast_ty.llvm_type(bcx.ccx).ptr_to()),
250-
Some(self.fn_ty.ret.layout.align))
250+
self.fn_ty.ret.layout.align)
251251
}
252252
};
253253
bcx.ret(llval);
@@ -653,7 +653,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
653653
// have scary latent bugs around.
654654

655655
let scratch = PlaceRef::alloca(bcx, arg.layout, "arg");
656-
base::memcpy_ty(bcx, scratch.llval, llval, op.layout, Some(align));
656+
base::memcpy_ty(bcx, scratch.llval, llval, op.layout, align);
657657
(scratch.llval, scratch.align, true)
658658
} else {
659659
(llval, align, true)
@@ -665,14 +665,14 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
665665
// Have to load the argument, maybe while casting it.
666666
if let PassMode::Cast(ty) = arg.mode {
667667
llval = bcx.load(bcx.pointercast(llval, ty.llvm_type(bcx.ccx).ptr_to()),
668-
Some(align.min(arg.layout.align)));
668+
align.min(arg.layout.align));
669669
} else {
670670
// We can't use `PlaceRef::load` here because the argument
671671
// may have a type we don't treat as immediate, but the ABI
672672
// used for this call is passing it by-value. In that case,
673673
// the load would just produce `OperandValue::Ref` instead
674674
// of the `OperandValue::Immediate` we need for the call.
675-
llval = bcx.load(llval, Some(align));
675+
llval = bcx.load(llval, align);
676676
if let layout::Abi::Scalar(ref scalar) = arg.layout.abi {
677677
if scalar.is_bool() {
678678
bcx.range_metadata(llval, 0..2);

src/librustc_trans/mir/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -530,11 +530,11 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
530530
// doesn't actually strip the offset when splitting the closure
531531
// environment into its components so it ends up out of bounds.
532532
let env_ptr = if !env_ref {
533-
let alloc = PlaceRef::alloca(bcx,
533+
let scratch = PlaceRef::alloca(bcx,
534534
bcx.ccx.layout_of(tcx.mk_mut_ptr(arg.layout.ty)),
535535
"__debuginfo_env_ptr");
536-
bcx.store(place.llval, alloc.llval, None);
537-
alloc.llval
536+
bcx.store(place.llval, scratch.llval, scratch.align);
537+
scratch.llval
538538
} else {
539539
place.llval
540540
};

src/librustc_trans/mir/operand.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,9 @@ impl<'a, 'tcx> OperandValue {
223223
match self {
224224
OperandValue::Ref(r, source_align) =>
225225
base::memcpy_ty(bcx, dest.llval, r, dest.layout,
226-
Some(source_align.min(dest.align))),
226+
source_align.min(dest.align)),
227227
OperandValue::Immediate(s) => {
228-
bcx.store(base::from_immediate(bcx, s), dest.llval, dest.non_abi_align());
228+
bcx.store(base::from_immediate(bcx, s), dest.llval, dest.align);
229229
}
230230
OperandValue::Pair(a, b) => {
231231
for (i, &x) in [a, b].iter().enumerate() {
@@ -234,7 +234,7 @@ impl<'a, 'tcx> OperandValue {
234234
if common::val_ty(x) == Type::i1(bcx.ccx) {
235235
llptr = bcx.pointercast(llptr, Type::i8p(bcx.ccx));
236236
}
237-
bcx.store(base::from_immediate(bcx, x), llptr, dest.non_abi_align());
237+
bcx.store(base::from_immediate(bcx, x), llptr, dest.align);
238238
}
239239
}
240240
}

src/librustc_trans/mir/place.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,6 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
8181
!self.llextra.is_null()
8282
}
8383

84-
pub fn non_abi_align(self) -> Option<Align> {
85-
if self.align.abi() >= self.layout.align.abi() {
86-
None
87-
} else {
88-
Some(self.align)
89-
}
90-
}
91-
9284
pub fn load(&self, bcx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> {
9385
debug!("PlaceRef::load: {:?}", self);
9486

@@ -135,7 +127,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
135127
let llval = if !const_llval.is_null() {
136128
const_llval
137129
} else {
138-
let load = bcx.load(self.llval, self.non_abi_align());
130+
let load = bcx.load(self.llval, self.align);
139131
if let layout::Abi::Scalar(ref scalar) = self.layout.abi {
140132
scalar_load_metadata(load, scalar);
141133
}
@@ -149,7 +141,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
149141
if scalar.is_bool() {
150142
llptr = bcx.pointercast(llptr, Type::i8p(bcx.ccx));
151143
}
152-
let load = bcx.load(llptr, self.non_abi_align());
144+
let load = bcx.load(llptr, self.align);
153145
scalar_load_metadata(load, scalar);
154146
if scalar.is_bool() {
155147
bcx.trunc(load, Type::i1(bcx.ccx))
@@ -338,7 +330,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
338330
.discriminant_for_variant(bcx.tcx(), variant_index)
339331
.to_u128_unchecked() as u64;
340332
bcx.store(C_int(ptr.layout.llvm_type(bcx.ccx), to as i64),
341-
ptr.llval, ptr.non_abi_align());
333+
ptr.llval, ptr.align);
342334
}
343335
layout::Variants::NicheFilling {
344336
dataful_variant,

src/librustc_trans/mir/rvalue.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
104104
let start = dest.project_index(&bcx, C_usize(bcx.ccx, 0)).llval;
105105

106106
if let OperandValue::Immediate(v) = tr_elem.val {
107-
let align = dest.non_abi_align()
108-
.unwrap_or(tr_elem.layout.align);
109-
let align = C_i32(bcx.ccx, align.abi() as i32);
107+
let align = C_i32(bcx.ccx, dest.align.abi() as i32);
110108
let size = C_usize(bcx.ccx, dest.layout.size.bytes());
111109

112110
// Use llvm.memset.p0i8.* to initialize all zero arrays

0 commit comments

Comments
 (0)