Skip to content

Commit bf87590

Browse files
eddybalexcrichton
authored andcommitted
rustc_codegen_llvm: don't overalign loads of pair operands.
1 parent ba9d7de commit bf87590

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

src/librustc_codegen_llvm/mir/place.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -150,17 +150,21 @@ impl PlaceRef<'ll, 'tcx> {
150150
});
151151
OperandValue::Immediate(base::to_immediate(bx, llval, self.layout))
152152
} else if let layout::Abi::ScalarPair(ref a, ref b) = self.layout.abi {
153-
let load = |i, scalar: &layout::Scalar| {
153+
let b_offset = a.value.size(bx.cx).abi_align(b.value.align(bx.cx));
154+
let load = |i, scalar: &layout::Scalar, align| {
154155
let llptr = bx.struct_gep(self.llval, i as u64);
155-
let load = bx.load(llptr, self.align);
156+
let load = bx.load(llptr, align);
156157
scalar_load_metadata(load, scalar);
157158
if scalar.is_bool() {
158159
bx.trunc(load, Type::i1(bx.cx))
159160
} else {
160161
load
161162
}
162163
};
163-
OperandValue::Pair(load(0, a), load(1, b))
164+
OperandValue::Pair(
165+
load(0, a, self.align),
166+
load(1, b, self.align.restrict_for_offset(b_offset)),
167+
)
164168
} else {
165169
OperandValue::Ref(self.llval, None, self.align)
166170
};

src/test/codegen/issue-56267-2.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 load from bar.1 should have alignment 4. Not checking
12+
// other loads here, as the alignment will be platform-dependent.
13+
14+
// CHECK: %{{.+}} = load i32, i32* %{{.+}}, align 4
15+
#[no_mangle]
16+
pub fn test(x: Foo<(i32, i32)>) -> (i32, i32) {
17+
x.bar
18+
}

0 commit comments

Comments
 (0)