Skip to content

Commit d8190af

Browse files
committed
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 computed correctly based on the element size.
1 parent 6bfb46e commit d8190af

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

src/librustc_codegen_ssa/mir/operand.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,21 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandValue<V> {
331331
bx.store_with_flags(val, dest.llval, dest.align, flags);
332332
}
333333
OperandValue::Pair(a, b) => {
334-
for (i, &x) in [a, b].iter().enumerate() {
335-
let llptr = bx.struct_gep(dest.llval, i as u64);
336-
let val = base::from_immediate(bx, x);
337-
bx.store_with_flags(val, llptr, dest.align, flags);
338-
}
334+
let (a_scalar, b_scalar) = match dest.layout.abi {
335+
layout::Abi::ScalarPair(ref a, ref b) => (a, b),
336+
_ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout)
337+
};
338+
let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi);
339+
340+
let llptr = bx.struct_gep(dest.llval, 0);
341+
let val = base::from_immediate(bx, a);
342+
let align = dest.align;
343+
bx.store_with_flags(val, llptr, align, flags);
344+
345+
let llptr = bx.struct_gep(dest.llval, 1);
346+
let val = base::from_immediate(bx, b);
347+
let align = dest.align.restrict_for_offset(b_offset);
348+
bx.store_with_flags(val, llptr, align, flags);
339349
}
340350
}
341351
}

src/test/codegen/issue-56267.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// compile-flags: -C no-prepopulate-passes
2+
3+
#![crate_type="rlib"]
4+
5+
#[allow(dead_code)]
6+
pub struct Foo<T> {
7+
foo: u64,
8+
bar: T,
9+
}
10+
11+
// The store writing to bar.1 should have alignment 4. Not checking
12+
// other stores here, as the alignment will be platform-dependent.
13+
14+
// CHECK: store i32 [[TMP1:%.+]], i32* [[TMP2:%.+]], align 4
15+
#[no_mangle]
16+
pub fn test(x: (i32, i32)) -> Foo<(i32, i32)> {
17+
Foo { foo: 0, bar: x }
18+
}

0 commit comments

Comments
 (0)