Skip to content

Commit 738868b

Browse files
committed
LLVM codegen: Don't emit zero-sized padding for fields
LLVM codegen: Don't emit zero-sized padding for whiles because that has no use and makes it impossible to generate the return types that LLVM expects for certain ARM SIMD intrinsics.
1 parent d54fbb9 commit 738868b

File tree

2 files changed

+36
-17
lines changed

2 files changed

+36
-17
lines changed

compiler/rustc_codegen_llvm/src/type_.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
262262
layout.is_llvm_scalar_pair()
263263
}
264264
fn backend_field_index(&self, layout: TyAndLayout<'tcx>, index: usize) -> u64 {
265-
layout.llvm_field_index(index)
265+
layout.llvm_field_index(self, index)
266266
}
267267
fn scalar_pair_element_backend_type(
268268
&self,

compiler/rustc_codegen_llvm/src/type_of.rs

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,12 @@ fn struct_llfields<'a, 'tcx>(
116116
);
117117
assert!(target_offset >= offset);
118118
let padding = target_offset - offset;
119-
let padding_align = prev_effective_align.min(effective_field_align);
120-
assert_eq!(offset.align_to(padding_align) + padding, target_offset);
121-
result.push(cx.type_padding_filler(padding, padding_align));
122-
debug!(" padding before: {:?}", padding);
123-
119+
if padding != Size::ZERO {
120+
let padding_align = prev_effective_align.min(effective_field_align);
121+
assert_eq!(offset.align_to(padding_align) + padding, target_offset);
122+
result.push(cx.type_padding_filler(padding, padding_align));
123+
debug!(" padding before: {:?}", padding);
124+
}
124125
result.push(field.llvm_type(cx));
125126
offset = target_offset + field.size;
126127
prev_effective_align = effective_field_align;
@@ -130,14 +131,15 @@ fn struct_llfields<'a, 'tcx>(
130131
bug!("layout: {:#?} stride: {:?} offset: {:?}", layout, layout.size, offset);
131132
}
132133
let padding = layout.size - offset;
133-
let padding_align = prev_effective_align;
134-
assert_eq!(offset.align_to(padding_align) + padding, layout.size);
135-
debug!(
136-
"struct_llfields: pad_bytes: {:?} offset: {:?} stride: {:?}",
137-
padding, offset, layout.size
138-
);
139-
result.push(cx.type_padding_filler(padding, padding_align));
140-
assert_eq!(result.len(), 1 + field_count * 2);
134+
if padding != Size::ZERO {
135+
let padding_align = prev_effective_align;
136+
assert_eq!(offset.align_to(padding_align) + padding, layout.size);
137+
debug!(
138+
"struct_llfields: pad_bytes: {:?} offset: {:?} stride: {:?}",
139+
padding, offset, layout.size
140+
);
141+
result.push(cx.type_padding_filler(padding, padding_align));
142+
}
141143
} else {
142144
debug!("struct_llfields: offset: {:?} stride: {:?}", offset, layout.size);
143145
}
@@ -177,7 +179,7 @@ pub trait LayoutLlvmExt<'tcx> {
177179
index: usize,
178180
immediate: bool,
179181
) -> &'a Type;
180-
fn llvm_field_index(&self, index: usize) -> u64;
182+
fn llvm_field_index<'a>(&self, cx: &CodegenCx<'a, 'tcx>, index: usize) -> u64;
181183
fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) -> Option<PointeeInfo>;
182184
}
183185

@@ -340,7 +342,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
340342
self.scalar_llvm_type_at(cx, scalar, offset)
341343
}
342344

343-
fn llvm_field_index(&self, index: usize) -> u64 {
345+
fn llvm_field_index<'a>(&self, cx: &CodegenCx<'a, 'tcx>, index: usize) -> u64 {
344346
match self.abi {
345347
Abi::Scalar(_) | Abi::ScalarPair(..) => {
346348
bug!("TyAndLayout::llvm_field_index({:?}): not applicable", self)
@@ -354,7 +356,24 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
354356

355357
FieldsShape::Array { .. } => index as u64,
356358

357-
FieldsShape::Arbitrary { .. } => 1 + (self.fields.memory_index(index) as u64) * 2,
359+
FieldsShape::Arbitrary { .. } => {
360+
let mut llvm_index = 0;
361+
let mut offset = Size::ZERO;
362+
for i in self.fields.index_by_increasing_offset() {
363+
let target_offset = self.fields.offset(i as usize);
364+
let field = self.field(cx, i);
365+
let padding = target_offset - offset;
366+
if padding != Size::ZERO {
367+
llvm_index += 1;
368+
}
369+
if i == index {
370+
return llvm_index;
371+
}
372+
offset = target_offset + field.size;
373+
llvm_index += 1;
374+
}
375+
bug!("TyAndLayout::llvm_field_index({:?}): index {} out of range", self, index)
376+
}
358377
}
359378
}
360379

0 commit comments

Comments
 (0)