Auto merge of #87254 - rusticstuff:rustc_codegen_llvm_dont_emit_zero_sized_padding, r=eddyb
LLVM codegen: Don't emit zero-sized padding for fields Currently padding is emitted before fields of a struct and at the end of the struct regardless of the ABI. Even if no padding is required zero-sized padding fields are emitted. This is not useful and - more importantly - it make it impossible to generate the exact vector types that LLVM expects for certain ARM SIMD intrinsics. This change should unblock the implementation of many ARM intrinsics using the `unadjusted` ABI, see https://github.com/rust-lang/stdarch/issues/1143#issuecomment-827404092. This is a proof of concept only because the field lookup now takes O(number of fields) time compared to O(1) before since it recalculates the mapping at every lookup. I would like to find out how big the performance impact actually is before implementing caching or restricting this behavior to the `unadjusted` ABI. cc `@SparrowLii` `@bjorn3` ([Discussion on internals](https://internals.rust-lang.org/t/feature-request-add-a-way-in-rustc-for-generating-struct-type-llvm-ir-without-paddings/15007))
This commit is contained in:
commit
47b41b7788
7 changed files with 107 additions and 41 deletions
|
|
@ -8,7 +8,7 @@ pub enum Align64 {
|
|||
A(u32),
|
||||
B(u32),
|
||||
}
|
||||
// CHECK: %Align64 = type { [0 x i32], i32, [15 x i32] }
|
||||
// CHECK: %Align64 = type { i32, [15 x i32] }
|
||||
|
||||
pub struct Nested64 {
|
||||
a: u8,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#[repr(align(64))]
|
||||
pub struct Align64(i32);
|
||||
// CHECK: %Align64 = type { [0 x i32], i32, [15 x i32] }
|
||||
// CHECK: %Align64 = type { i32, [15 x i32] }
|
||||
|
||||
pub struct Nested64 {
|
||||
a: Align64,
|
||||
|
|
@ -13,20 +13,20 @@ pub struct Nested64 {
|
|||
c: i32,
|
||||
d: i8,
|
||||
}
|
||||
// CHECK: %Nested64 = type { [0 x i64], %Align64, [0 x i32], i32, [0 x i32], i32, [0 x i8], i8, [55 x i8] }
|
||||
// CHECK: %Nested64 = type { %Align64, i32, i32, i8, [55 x i8] }
|
||||
|
||||
pub enum Enum4 {
|
||||
A(i32),
|
||||
B(i32),
|
||||
}
|
||||
// CHECK: %"Enum4::A" = type { [1 x i32], i32, [0 x i32] }
|
||||
// CHECK: %"Enum4::A" = type { [1 x i32], i32 }
|
||||
|
||||
pub enum Enum64 {
|
||||
A(Align64),
|
||||
B(i32),
|
||||
}
|
||||
// CHECK: %Enum64 = type { [0 x i32], i32, [31 x i32] }
|
||||
// CHECK: %"Enum64::A" = type { [8 x i64], %Align64, [0 x i64] }
|
||||
// CHECK: %Enum64 = type { i32, [31 x i32] }
|
||||
// CHECK: %"Enum64::A" = type { [8 x i64], %Align64 }
|
||||
|
||||
// CHECK-LABEL: @align64
|
||||
#[no_mangle]
|
||||
|
|
|
|||
14
src/test/codegen/unpadded-simd.rs
Normal file
14
src/test/codegen/unpadded-simd.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Make sure that no 0-sized padding is inserted in structs and that
|
||||
// structs are represented as expected by Neon intrinsics in LLVM.
|
||||
// See #87254.
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(repr_simd)]
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(simd)]
|
||||
pub struct int16x4_t(pub i16, pub i16, pub i16, pub i16);
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct int16x4x2_t(pub int16x4_t, pub int16x4_t);
|
||||
// CHECK: %int16x4x2_t = type { <4 x i16>, <4 x i16> }
|
||||
Loading…
Add table
Add a link
Reference in a new issue