Skip to content

Commit 3ea5cfa

Browse files
committed
Tolerate overaligned MIR constants for codegen.
1 parent 4283aea commit 3ea5cfa

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

compiler/rustc_codegen_ssa/src/mir/operand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
132132
offset: Size,
133133
) -> Self {
134134
let alloc_align = alloc.inner().align;
135-
assert_eq!(alloc_align, layout.align.abi);
135+
assert!(alloc_align >= layout.align.abi);
136136

137137
let read_scalar = |start, size, s: abi::Scalar, ty| {
138138
match alloc.0.read_scalar(

tests/codegen/overaligned-constant.rs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// GVN may create indirect constants with higher alignment than their type requires. Verify that we
2+
// do not ICE during codegen, and that the LLVM constant has the higher alignment.
3+
//
4+
// compile-flags: -O -Zmir-enable-passes=+GVN -Cdebuginfo=2
5+
// compile-flags: -Cno-prepopulate-passes
6+
// only-64bit
7+
8+
struct S(i32);
9+
10+
struct SmallStruct(f32, Option<S>, &'static [f32]);
11+
12+
fn main() {
13+
let mut s = S(1);
14+
15+
s.0 = 3;
16+
17+
// SMALL_VAL corresponds to a MIR allocation with alignment 8.
18+
const SMALL_VAL: SmallStruct = SmallStruct(4., Some(S(1)), &[]);
19+
20+
// In pre-codegen MIR:
21+
// `a` is a scalar 4.
22+
// `b` is an indirect constant at `SMALL_VAL`'s alloc with 0 offset.
23+
// `c` is the empty slice.
24+
//
25+
// As a consequence, during codegen, we create a LLVM allocation for `SMALL_VAL`, with
26+
// alignment 8, but only use the `Option<S>` field, at offset 0 with alignment 4.
27+
let SmallStruct(a, b, c) = SMALL_VAL;
28+
}
29+
30+
// CHECK: @0 = private unnamed_addr constant
31+
// CHECK-SAME: , align 8

0 commit comments

Comments
 (0)