Skip to content

Commit 67d2c9f

Browse files
committed
rustc_codegen_ssa: don't use LLVM struct types for field offsets.
1 parent 64eb9ab commit 67d2c9f

File tree

7 files changed

+17
-62
lines changed

7 files changed

+17
-62
lines changed

compiler/rustc_codegen_gcc/src/type_of.rs

-23
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ pub trait LayoutGccExt<'tcx> {
137137
fn immediate_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>;
138138
fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Scalar, offset: Size) -> Type<'gcc>;
139139
fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize, immediate: bool) -> Type<'gcc>;
140-
fn gcc_field_index(&self, index: usize) -> u64;
141140
fn pointee_info_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, offset: Size) -> Option<PointeeInfo>;
142141
}
143142

@@ -311,24 +310,6 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
311310
self.scalar_gcc_type_at(cx, scalar, offset)
312311
}
313312

314-
fn gcc_field_index(&self, index: usize) -> u64 {
315-
match self.abi {
316-
Abi::Scalar(_) | Abi::ScalarPair(..) => {
317-
bug!("TyAndLayout::gcc_field_index({:?}): not applicable", self)
318-
}
319-
_ => {}
320-
}
321-
match self.fields {
322-
FieldsShape::Primitive | FieldsShape::Union(_) => {
323-
bug!("TyAndLayout::gcc_field_index({:?}): not applicable", self)
324-
}
325-
326-
FieldsShape::Array { .. } => index as u64,
327-
328-
FieldsShape::Arbitrary { .. } => 1 + (self.fields.memory_index(index) as u64) * 2,
329-
}
330-
}
331-
332313
fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) -> Option<PointeeInfo> {
333314
if let Some(&pointee) = cx.pointee_infos.borrow().get(&(self.ty, offset)) {
334315
return pointee;
@@ -358,10 +339,6 @@ impl<'gcc, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
358339
layout.is_gcc_scalar_pair()
359340
}
360341

361-
fn backend_field_index(&self, layout: TyAndLayout<'tcx>, index: usize) -> u64 {
362-
layout.gcc_field_index(index)
363-
}
364-
365342
fn scalar_pair_element_backend_type(&self, layout: TyAndLayout<'tcx>, index: usize, immediate: bool) -> Type<'gcc> {
366343
layout.scalar_pair_element_gcc_type(self, index, immediate)
367344
}

compiler/rustc_codegen_llvm/src/type_.rs

-3
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,6 @@ impl<'ll, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
265265
fn is_backend_scalar_pair(&self, layout: TyAndLayout<'tcx>) -> bool {
266266
layout.is_llvm_scalar_pair()
267267
}
268-
fn backend_field_index(&self, layout: TyAndLayout<'tcx>, index: usize) -> u64 {
269-
layout.llvm_field_index(self, index)
270-
}
271268
fn scalar_pair_element_backend_type(
272269
&self,
273270
layout: TyAndLayout<'tcx>,

compiler/rustc_codegen_llvm/src/type_of.rs

+2
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ pub trait LayoutLlvmExt<'tcx> {
194194
index: usize,
195195
immediate: bool,
196196
) -> &'a Type;
197+
// FIXME(eddyb) remove (used only by `va_arg::emit_aapcs_va_arg`).
197198
fn llvm_field_index<'a>(&self, cx: &CodegenCx<'a, 'tcx>, index: usize) -> u64;
198199
fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) -> Option<PointeeInfo>;
199200
}
@@ -366,6 +367,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
366367
self.scalar_llvm_type_at(cx, scalar, offset)
367368
}
368369

370+
// FIXME(eddyb) remove (used only by `va_arg::emit_aapcs_va_arg`).
369371
fn llvm_field_index<'a>(&self, cx: &CodegenCx<'a, 'tcx>, index: usize) -> u64 {
370372
match self.abi {
371373
Abi::Scalar(_) | Abi::ScalarPair(..) => {

compiler/rustc_codegen_llvm/src/va_arg.rs

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ fn emit_aapcs_va_arg<'ll, 'tcx>(
110110
let offset_align = Align::from_bytes(4).unwrap();
111111

112112
let gr_type = target_ty.is_any_ptr() || target_ty.is_integral();
113+
// FIXME(eddyb) this should use the higher-level `PlaceRef` APIs.
113114
let (reg_off, reg_top_index, slot_size) = if gr_type {
114115
let gr_offs =
115116
bx.struct_gep(va_list_ty, va_list_addr, va_list_layout.llvm_field_index(bx.cx, 3));

compiler/rustc_codegen_ssa/src/mir/place.rs

+11-32
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_middle::mir;
1010
use rustc_middle::mir::tcx::PlaceTy;
1111
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
1212
use rustc_middle::ty::{self, Ty};
13-
use rustc_target::abi::{Abi, Align, FieldsShape, Int, TagEncoding};
13+
use rustc_target::abi::{Align, FieldsShape, Int, TagEncoding};
1414
use rustc_target::abi::{VariantIdx, Variants};
1515

1616
#[derive(Copy, Clone, Debug)]
@@ -93,37 +93,15 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
9393
let effective_field_align = self.align.restrict_for_offset(offset);
9494

9595
let mut simple = || {
96-
let llval = match self.layout.abi {
97-
_ if offset.bytes() == 0 => {
98-
// Unions and newtypes only use an offset of 0.
99-
// Also handles the first field of Scalar, ScalarPair, and Vector layouts.
100-
self.llval
101-
}
102-
Abi::ScalarPair(a, b)
103-
if offset == a.size(bx.cx()).align_to(b.align(bx.cx()).abi) =>
104-
{
105-
// Offset matches second field.
106-
let ty = bx.backend_type(self.layout);
107-
bx.struct_gep(ty, self.llval, 1)
108-
}
109-
Abi::Scalar(_) | Abi::ScalarPair(..) | Abi::Vector { .. } if field.is_zst() => {
110-
// ZST fields are not included in Scalar, ScalarPair, and Vector layouts, so manually offset the pointer.
111-
let byte_ptr = bx.pointercast(self.llval, bx.cx().type_i8p());
112-
bx.gep(bx.cx().type_i8(), byte_ptr, &[bx.const_usize(offset.bytes())])
113-
}
114-
Abi::Scalar(_) | Abi::ScalarPair(..) => {
115-
// All fields of Scalar and ScalarPair layouts must have been handled by this point.
116-
// Vector layouts have additional fields for each element of the vector, so don't panic in that case.
117-
bug!(
118-
"offset of non-ZST field `{:?}` does not match layout `{:#?}`",
119-
field,
120-
self.layout
121-
);
122-
}
123-
_ => {
124-
let ty = bx.backend_type(self.layout);
125-
bx.struct_gep(ty, self.llval, bx.cx().backend_field_index(self.layout, ix))
126-
}
96+
let llval = if offset.bytes() == 0 {
97+
self.llval
98+
} else {
99+
let byte_ptr = bx.pointercast(self.llval, bx.cx().type_i8p());
100+
// FIXME(eddyb) when can this not be `inbounds`? ZSTs?
101+
// (but since `offset` is larger than `0`, that would mean the
102+
// allocation the place points into has at least one byte, so
103+
// any possible offset in the layout *should* be in-bounds)
104+
bx.inbounds_gep(bx.cx().type_i8(), byte_ptr, &[bx.const_usize(offset.bytes())])
127105
};
128106
PlaceRef {
129107
// HACK(eddyb): have to bitcast pointers until LLVM removes pointee types.
@@ -189,6 +167,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
189167

190168
// Cast and adjust pointer.
191169
let byte_ptr = bx.pointercast(self.llval, bx.cx().type_i8p());
170+
// FIXME(eddyb) this should be `inbounds` (why not? ZSTs?)
192171
let byte_ptr = bx.gep(bx.cx().type_i8(), byte_ptr, &[offset]);
193172

194173
// Finally, cast back to the type expected.

compiler/rustc_codegen_ssa/src/traits/type_.rs

-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
108108
fn immediate_backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type;
109109
fn is_backend_immediate(&self, layout: TyAndLayout<'tcx>) -> bool;
110110
fn is_backend_scalar_pair(&self, layout: TyAndLayout<'tcx>) -> bool;
111-
fn backend_field_index(&self, layout: TyAndLayout<'tcx>, index: usize) -> u64;
112111
fn scalar_pair_element_backend_type(
113112
&self,
114113
layout: TyAndLayout<'tcx>,

src/test/codegen/zst-offset.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub fn helper(_: usize) {
1313
// CHECK-LABEL: @scalar_layout
1414
#[no_mangle]
1515
pub fn scalar_layout(s: &(u64, ())) {
16-
// CHECK: getelementptr i8, {{.+}}, [[USIZE]] 8
16+
// CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 8
1717
let x = &s.1;
1818
&x; // keep variable in an alloca
1919
}
@@ -22,7 +22,7 @@ pub fn scalar_layout(s: &(u64, ())) {
2222
// CHECK-LABEL: @scalarpair_layout
2323
#[no_mangle]
2424
pub fn scalarpair_layout(s: &(u64, u32, ())) {
25-
// CHECK: getelementptr i8, {{.+}}, [[USIZE]] 12
25+
// CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 12
2626
let x = &s.2;
2727
&x; // keep variable in an alloca
2828
}
@@ -34,7 +34,7 @@ pub struct U64x4(u64, u64, u64, u64);
3434
// CHECK-LABEL: @vector_layout
3535
#[no_mangle]
3636
pub fn vector_layout(s: &(U64x4, ())) {
37-
// CHECK: getelementptr i8, {{.+}}, [[USIZE]] 32
37+
// CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 32
3838
let x = &s.1;
3939
&x; // keep variable in an alloca
4040
}

0 commit comments

Comments
 (0)