Skip to content

Commit

Permalink
Auto merge of rust-lang#119056 - cjgillot:codegen-overalign, r=wesley…
Browse files Browse the repository at this point in the history
…wiser

Tolerate overaligned MIR constants for codegen.

Fixes rust-lang#117761

cc `@saethlin`
  • Loading branch information
bors committed Dec 21, 2023
2 parents 3694a6b + 503af0d commit 920e005
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
offset: Size,
) -> Self {
let alloc_align = alloc.inner().align;
assert_eq!(alloc_align, layout.align.abi);
assert!(alloc_align >= layout.align.abi);

let read_scalar = |start, size, s: abi::Scalar, ty| {
match alloc.0.read_scalar(
Expand Down
36 changes: 36 additions & 0 deletions tests/codegen/overaligned-constant.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// GVN may create indirect constants with higher alignment than their type requires. Verify that we
// do not ICE during codegen, and that the LLVM constant has the higher alignment.
//
// compile-flags: -Zmir-opt-level=0 -Zmir-enable-passes=+GVN
// compile-flags: -Cno-prepopulate-passes
// only-64bit

struct S(i32);

struct SmallStruct(f32, Option<S>, &'static [f32]);

// CHECK: @0 = private unnamed_addr constant
// CHECK-SAME: , align 8

fn main() {
// CHECK-LABEL: @_ZN20overaligned_constant4main
// CHECK: [[full:%_.*]] = alloca %SmallStruct, align 8
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[full]], ptr align 8 @0, i64 32, i1 false)
// CHECK: %b.0 = load i32, ptr @0, align 4,
// CHECK: %b.1 = load i32, ptr getelementptr inbounds ({ i32, i32 }, ptr @0, i32 0, i32 1), align 4
let mut s = S(1);

s.0 = 3;

// SMALL_VAL corresponds to a MIR allocation with alignment 8.
const SMALL_VAL: SmallStruct = SmallStruct(4., Some(S(1)), &[]);

// In pre-codegen MIR:
// `a` is a scalar 4.
// `b` is an indirect constant at `SMALL_VAL`'s alloc with 0 offset.
// `c` is the empty slice.
//
// As a consequence, during codegen, we create a LLVM allocation for `SMALL_VAL`, with
// alignment 8, but only use the `Option<S>` field, at offset 0 with alignment 4.
let SmallStruct(a, b, c) = SMALL_VAL;
}

0 comments on commit 920e005

Please sign in to comment.