Skip to content

Commit

Permalink
Auto merge of #56300 - nikic:issue-56267, r=eddyb
Browse files Browse the repository at this point in the history
Fix alignment of stores to scalar pair

The alignment for the second element of a scalar pair is not the same as for the first element, make sure it is calculated correctly. This fixes #56267.

r? @eddyb
  • Loading branch information
bors committed Nov 29, 2018
2 parents b68fc18 + d8190af commit 5f387a6
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
20 changes: 15 additions & 5 deletions src/librustc_codegen_ssa/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,21 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandValue<V> {
bx.store_with_flags(val, dest.llval, dest.align, flags);
}
OperandValue::Pair(a, b) => {
for (i, &x) in [a, b].iter().enumerate() {
let llptr = bx.struct_gep(dest.llval, i as u64);
let val = base::from_immediate(bx, x);
bx.store_with_flags(val, llptr, dest.align, flags);
}
let (a_scalar, b_scalar) = match dest.layout.abi {
layout::Abi::ScalarPair(ref a, ref b) => (a, b),
_ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout)
};
let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi);

let llptr = bx.struct_gep(dest.llval, 0);
let val = base::from_immediate(bx, a);
let align = dest.align;
bx.store_with_flags(val, llptr, align, flags);

let llptr = bx.struct_gep(dest.llval, 1);
let val = base::from_immediate(bx, b);
let align = dest.align.restrict_for_offset(b_offset);
bx.store_with_flags(val, llptr, align, flags);
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions src/test/codegen/issue-56267.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// compile-flags: -C no-prepopulate-passes

#![crate_type="rlib"]

#[allow(dead_code)]
pub struct Foo<T> {
foo: u64,
bar: T,
}

// The store writing to bar.1 should have alignment 4. Not checking
// other stores here, as the alignment will be platform-dependent.

// CHECK: store i32 [[TMP1:%.+]], i32* [[TMP2:%.+]], align 4
#[no_mangle]
pub fn test(x: (i32, i32)) -> Foo<(i32, i32)> {
Foo { foo: 0, bar: x }
}

0 comments on commit 5f387a6

Please sign in to comment.