mirror of https://github.com/rust-lang/rust
38 lines
1.4 KiB
Rust
38 lines
1.4 KiB
Rust
// 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 --crate-type=lib
|
|
//@ only-64bit
|
|
|
|
struct S(i32);
|
|
|
|
struct SmallStruct(f32, Option<S>, &'static [f32]);
|
|
|
|
// CHECK: @0 = private unnamed_addr constant
|
|
// CHECK-SAME: , align 8
|
|
|
|
#[no_mangle]
|
|
pub fn overaligned_constant() {
|
|
// CHECK-LABEL: @overaligned_constant
|
|
// CHECK: [[full:%_.*]] = alloca [32 x i8], 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 ({{.*}}), 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;
|
|
}
|