Code change:
<ins> // 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; } </ins>

Related discussion:
text: Error: That's this: The GVN MIR diff is this: searched nightlies: from nightly-2023-06-01 to nightly-2023-11-08 regressed nightly: nightly-2023-10-30 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.7</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
This issue is a bit old but I've now minimized the reproducer, it's in the description. the assertion that's failing here looks to me like it is simply too picky, and it should be checking if the alignment of the allocation is the alignment of the type we're reading from it, instead of exactly equal. Do you agree that this is just a too-picky assertion?
I agree the assertion is just too picky. I expect the subtlety of needing to pass the larger alignment for the llvm constant.
I can't figure out what you mean here. What LLVM constant? Why is there subtelty? Maybe I just don't understand what's going on with GVN here, I'm assuming that GVN has merged two constants together so that we're now loading part of a more-aligned constant to get a less-aligned one. Is that wrong?
I mean, this is codegen code. It creates a constant for llvm. That constant has some alignment. We need to pick the right one, between the lhs and rhs of the assert.
Where are we picking an alignment? Is it down here?
smaller repro: <!-- ICE: Rustc '-Zmir-opt-level=5 -Cdebuginfo=2 -ooutputfile -Zdump-mir-dir=dir' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' File: --auto-reduced (treereduce-rust): &lt;details&lt;summary&lt;strongoriginal code&lt;/strong&lt;/summary&lt;poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: --
I don't really know.