diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2023-12-17 22:56:42 +0000 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2023-12-17 22:56:42 +0000 |
| commit | 3ea5cfaa11ce82b3d16385e16b770b4749463406 (patch) | |
| tree | e3b94d84f4910de9304255645e6da1f17f1a472a | |
| parent | 4283aeaca5c0c14864d4af3369a42c6b8b21f80f (diff) | |
| download | rust-3ea5cfaa11ce82b3d16385e16b770b4749463406.tar.gz rust-3ea5cfaa11ce82b3d16385e16b770b4749463406.zip | |
Tolerate overaligned MIR constants for codegen.
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/operand.rs | 2 | ||||
| -rw-r--r-- | tests/codegen/overaligned-constant.rs | 31 |
2 files changed, 32 insertions, 1 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index e8c58f6b6f8..794cbd315b7 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -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( diff --git a/tests/codegen/overaligned-constant.rs b/tests/codegen/overaligned-constant.rs new file mode 100644 index 00000000000..5f4dc3173c8 --- /dev/null +++ b/tests/codegen/overaligned-constant.rs @@ -0,0 +1,31 @@ +// 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: -O -Zmir-enable-passes=+GVN -Cdebuginfo=2 +// compile-flags: -Cno-prepopulate-passes +// only-64bit + +struct S(i32); + +struct SmallStruct(f32, Option<S>, &'static [f32]); + +fn main() { + 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; +} + +// CHECK: @0 = private unnamed_addr constant +// CHECK-SAME: , align 8 |
