diff options
| author | Nikita Popov <nikita.ppv@gmail.com> | 2018-12-21 23:12:15 +0100 |
|---|---|---|
| committer | Nikita Popov <nikita.ppv@gmail.com> | 2018-12-21 23:51:55 +0100 |
| commit | 097d39d8ecb2d8aa828393c66e85716081188793 (patch) | |
| tree | aa2379ca26f87947862b7528cd3087e04c092f27 /src/librustc_codegen_ssa | |
| parent | 6d34ec18c7d7e574553f6347ecf08e1e1c45c13d (diff) | |
| download | rust-097d39d8ecb2d8aa828393c66e85716081188793.tar.gz rust-097d39d8ecb2d8aa828393c66e85716081188793.zip | |
Fix alignment for array indexing
We need to reduce the alignment with the used offset. If the offset isn't known, we need to reduce with the element size to support arbitrary offsets.
Diffstat (limited to 'src/librustc_codegen_ssa')
| -rw-r--r-- | src/librustc_codegen_ssa/mir/place.rs | 13 | ||||
| -rw-r--r-- | src/librustc_codegen_ssa/mir/rvalue.rs | 3 |
2 files changed, 13 insertions, 3 deletions
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 90aa9f6cbc7..5fad4a24b26 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -335,11 +335,20 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { bx: &mut Bx, llindex: V ) -> Self { + // Statically compute the offset if we can, otherwise just use the element size, + // as this will yield the lowest alignment. + let layout = self.layout.field(bx, 0); + let offset = if bx.is_const_integral(llindex) { + layout.size.checked_mul(bx.const_to_uint(llindex), bx).unwrap_or(layout.size) + } else { + layout.size + }; + PlaceRef { llval: bx.inbounds_gep(self.llval, &[bx.cx().const_usize(0), llindex]), llextra: None, - layout: self.layout.field(bx.cx(), 0), - align: self.align + layout, + align: self.align.restrict_for_offset(offset), } } diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index c932ffd1c1b..052342dd759 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -131,8 +131,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end); header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb()); + let align = dest.align.restrict_for_offset(dest.layout.field(bx.cx(), 0).size); cg_elem.val.store(&mut body_bx, - PlaceRef::new_sized(current, cg_elem.layout, dest.align)); + PlaceRef::new_sized(current, cg_elem.layout, align)); let next = body_bx.inbounds_gep(current, &[bx.cx().const_usize(1)]); body_bx.br(header_bx.llbb()); |
