});
OperandValue::Immediate(to_immediate(self, llval, place.layout))
} else if let layout::Abi::ScalarPair(ref a, ref b) = place.layout.abi {
- let mut load = |i, scalar: &layout::Scalar| {
+ let b_offset = a.value.size(self).align_to(b.value.align(self).abi);
+
+ let mut load = |i, scalar: &layout::Scalar, align| {
let llptr = self.struct_gep(place.llval, i as u64);
- let load = self.load(llptr, place.align);
+ let load = self.load(llptr, align);
scalar_load_metadata(self, load, scalar);
if scalar.is_bool() {
self.trunc(load, self.cx().type_i1())
load
}
};
- OperandValue::Pair(load(0, a), load(1, b))
+
+ OperandValue::Pair(
+ load(0, a, place.align),
+ load(1, b, place.align.restrict_for_offset(b_offset)),
+ )
} else {
OperandValue::Ref(place.llval, None, place.align)
};
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);
}
}
}
}
ModuleOrUniformRoot::ExternPrelude => {
assert!(!restricted_shadowing);
- return if let Some(binding) = self.extern_prelude_get(ident, !record_used) {
+ return if ns != TypeNS {
+ Err((Determined, Weak::No))
+ } else if let Some(binding) = self.extern_prelude_get(ident, !record_used) {
Ok(binding)
} else if !self.graph_root.unresolved_invocations.borrow().is_empty() {
// Macro-expanded `extern crate` items can add names to extern prelude.
--- /dev/null
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type="rlib"]
+
+#[allow(dead_code)]
+pub struct Foo<T> {
+ foo: u64,
+ bar: T,
+}
+
+// The load from bar.1 should have alignment 4. Not checking
+// other loads here, as the alignment will be platform-dependent.
+
+// CHECK: %{{.+}} = load i32, i32* %{{.+}}, align 4
+#[no_mangle]
+pub fn test(x: Foo<(i32, i32)>) -> (i32, i32) {
+ x.bar
+}
--- /dev/null
+// 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 }
+}
--- /dev/null
+// compile-pass
+// edition:2018
+
+use ::std;
+
+fn main() {
+ let std = 10;
+}
-Subproject commit 754b4c07233ee18820265bd18467aa82263f9a3a
+Subproject commit b2601beb35b56fd33bd387a1faeccd3ae02352ed