about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-12-17 22:56:42 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2023-12-17 22:56:42 +0000
commit3ea5cfaa11ce82b3d16385e16b770b4749463406 (patch)
treee3b94d84f4910de9304255645e6da1f17f1a472a
parent4283aeaca5c0c14864d4af3369a42c6b8b21f80f (diff)
downloadrust-3ea5cfaa11ce82b3d16385e16b770b4749463406.tar.gz
rust-3ea5cfaa11ce82b3d16385e16b770b4749463406.zip
Tolerate overaligned MIR constants for codegen.
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs2
-rw-r--r--tests/codegen/overaligned-constant.rs31
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