mirror of https://github.com/rust-lang/rust.git
always use gep inbounds i8 (ptradd) for field offsets
This commit is contained in:
parent
71ffdf7ff7
commit
123015e722
|
@ -151,7 +151,6 @@ pub trait LayoutGccExt<'tcx> {
|
|||
fn immediate_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>;
|
||||
fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Scalar, offset: Size) -> Type<'gcc>;
|
||||
fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize) -> Type<'gcc>;
|
||||
fn gcc_field_index(&self, index: usize) -> u64;
|
||||
fn pointee_info_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, offset: Size) -> Option<PointeeInfo>;
|
||||
}
|
||||
|
||||
|
@ -304,24 +303,6 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
|
|||
self.scalar_gcc_type_at(cx, scalar, offset)
|
||||
}
|
||||
|
||||
fn gcc_field_index(&self, index: usize) -> u64 {
|
||||
match self.abi {
|
||||
Abi::Scalar(_) | Abi::ScalarPair(..) => {
|
||||
bug!("TyAndLayout::gcc_field_index({:?}): not applicable", self)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
match self.fields {
|
||||
FieldsShape::Primitive | FieldsShape::Union(_) => {
|
||||
bug!("TyAndLayout::gcc_field_index({:?}): not applicable", self)
|
||||
}
|
||||
|
||||
FieldsShape::Array { .. } => index as u64,
|
||||
|
||||
FieldsShape::Arbitrary { .. } => 1 + (self.fields.memory_index(index) as u64) * 2,
|
||||
}
|
||||
}
|
||||
|
||||
fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) -> Option<PointeeInfo> {
|
||||
if let Some(&pointee) = cx.pointee_infos.borrow().get(&(self.ty, offset)) {
|
||||
return pointee;
|
||||
|
@ -351,10 +332,6 @@ impl<'gcc, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|||
layout.is_gcc_scalar_pair()
|
||||
}
|
||||
|
||||
fn backend_field_index(&self, layout: TyAndLayout<'tcx>, index: usize) -> u64 {
|
||||
layout.gcc_field_index(index)
|
||||
}
|
||||
|
||||
fn scalar_pair_element_backend_type(&self, layout: TyAndLayout<'tcx>, index: usize, _immediate: bool) -> Type<'gcc> {
|
||||
layout.scalar_pair_element_gcc_type(self, index)
|
||||
}
|
||||
|
|
|
@ -250,9 +250,6 @@ impl<'ll, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
fn is_backend_scalar_pair(&self, layout: TyAndLayout<'tcx>) -> bool {
|
||||
layout.is_llvm_scalar_pair()
|
||||
}
|
||||
fn backend_field_index(&self, layout: TyAndLayout<'tcx>, index: usize) -> u64 {
|
||||
layout.llvm_field_index(self, index)
|
||||
}
|
||||
fn scalar_pair_element_backend_type(
|
||||
&self,
|
||||
layout: TyAndLayout<'tcx>,
|
||||
|
|
|
@ -9,7 +9,7 @@ use rustc_middle::mir;
|
|||
use rustc_middle::mir::tcx::PlaceTy;
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_target::abi::{Abi, Align, FieldsShape, Int, Pointer, TagEncoding};
|
||||
use rustc_target::abi::{Align, FieldsShape, Int, Pointer, TagEncoding};
|
||||
use rustc_target::abi::{VariantIdx, Variants};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
@ -102,34 +102,10 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
|
|||
// `simple` is called when we don't need to adjust the offset to
|
||||
// the dynamic alignment of the field.
|
||||
let mut simple = || {
|
||||
let llval = match self.layout.abi {
|
||||
_ if offset.bytes() == 0 => {
|
||||
// Unions and newtypes only use an offset of 0.
|
||||
// Also handles the first field of Scalar, ScalarPair, and Vector layouts.
|
||||
self.llval
|
||||
}
|
||||
Abi::ScalarPair(..) => {
|
||||
// FIXME(nikic): Generate this for all ABIs.
|
||||
bx.inbounds_gep(bx.type_i8(), self.llval, &[bx.const_usize(offset.bytes())])
|
||||
}
|
||||
Abi::Scalar(_) | Abi::Vector { .. } if field.is_zst() => {
|
||||
// ZST fields (even some that require alignment) are not included in Scalar,
|
||||
// ScalarPair, and Vector layouts, so manually offset the pointer.
|
||||
bx.gep(bx.cx().type_i8(), self.llval, &[bx.const_usize(offset.bytes())])
|
||||
}
|
||||
Abi::Scalar(_) => {
|
||||
// All fields of Scalar layouts must have been handled by this point.
|
||||
// Vector layouts have additional fields for each element of the vector, so don't panic in that case.
|
||||
bug!(
|
||||
"offset of non-ZST field `{:?}` does not match layout `{:#?}`",
|
||||
field,
|
||||
self.layout
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
let ty = bx.backend_type(self.layout);
|
||||
bx.struct_gep(ty, self.llval, bx.cx().backend_field_index(self.layout, ix))
|
||||
}
|
||||
let llval = if offset.bytes() == 0 {
|
||||
self.llval
|
||||
} else {
|
||||
bx.inbounds_gep(bx.type_i8(), self.llval, &[bx.const_usize(offset.bytes())])
|
||||
};
|
||||
PlaceRef {
|
||||
llval,
|
||||
|
|
|
@ -111,7 +111,6 @@ pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
|
|||
fn immediate_backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type;
|
||||
fn is_backend_immediate(&self, layout: TyAndLayout<'tcx>) -> bool;
|
||||
fn is_backend_scalar_pair(&self, layout: TyAndLayout<'tcx>) -> bool;
|
||||
fn backend_field_index(&self, layout: TyAndLayout<'tcx>, index: usize) -> u64;
|
||||
fn scalar_pair_element_backend_type(
|
||||
&self,
|
||||
layout: TyAndLayout<'tcx>,
|
||||
|
|
|
@ -26,7 +26,6 @@ pub enum Enum64 {
|
|||
B(i32),
|
||||
}
|
||||
// CHECK: %Enum64 = type { i32, [31 x i32] }
|
||||
// CHECK: %"Enum64::A" = type { [8 x i64], %Align64 }
|
||||
|
||||
// CHECK-LABEL: @align64
|
||||
#[no_mangle]
|
||||
|
|
|
@ -94,9 +94,9 @@ pub fn store_struct(x: &mut Struct) {
|
|||
// CHECK-SAME: align 16 dereferenceable(32) %x
|
||||
// CHECK: [[TMP:%.*]] = alloca %Struct, align 16
|
||||
// CHECK: store i32 1, ptr [[TMP]], align 16
|
||||
// CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds %Struct, ptr [[TMP]], i32 0, i32 1
|
||||
// CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[TMP]], i64 4
|
||||
// CHECK-NEXT: store i32 2, ptr [[GEP1]], align 4
|
||||
// CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds %Struct, ptr [[TMP]], i32 0, i32 3
|
||||
// CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[TMP]], i64 16
|
||||
// CHECK-NEXT: store i128 3, ptr [[GEP2]], align 16
|
||||
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 16 %x, ptr align 16 [[TMP]], i64 32, i1 false)
|
||||
*x = Struct { a: 1, b: 2, c: 3 };
|
||||
|
|
|
@ -16,8 +16,8 @@ pub fn outer_function(x: S, y: S) -> usize {
|
|||
// when generating debuginfo.
|
||||
// CHECK-LABEL: @outer_function
|
||||
// CHECK: [[spill:%.*]] = alloca %"{closure@{{.*.rs}}:9:23: 9:25}"
|
||||
// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds %"{closure@{{.*.rs}}:9:23: 9:25}", ptr [[spill]]
|
||||
// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds i8, ptr [[spill]]
|
||||
// CHECK-NOT: [[load:%.*]] = load ptr, ptr
|
||||
// CHECK: call void @llvm.lifetime.start{{.*}}({{.*}}, ptr [[spill]])
|
||||
// CHECK: [[inner:%.*]] = getelementptr inbounds %"{{.*}}", ptr [[spill]]
|
||||
// CHECK: [[inner:%.*]] = getelementptr inbounds i8, ptr [[spill]]
|
||||
// CHECK: call void @llvm.memcpy{{.*}}(ptr {{align .*}} [[inner]], ptr {{align .*}} %x
|
||||
|
|
|
@ -13,7 +13,7 @@ pub fn helper(_: usize) {
|
|||
// CHECK-LABEL: @scalar_layout
|
||||
#[no_mangle]
|
||||
pub fn scalar_layout(s: &(u64, ())) {
|
||||
// CHECK: getelementptr i8, {{.+}}, [[USIZE]] 8
|
||||
// CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 8
|
||||
let x = &s.1;
|
||||
witness(&x); // keep variable in an alloca
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ pub struct U64x4(u64, u64, u64, u64);
|
|||
// CHECK-LABEL: @vector_layout
|
||||
#[no_mangle]
|
||||
pub fn vector_layout(s: &(U64x4, ())) {
|
||||
// CHECK: getelementptr i8, {{.+}}, [[USIZE]] 32
|
||||
// CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 32
|
||||
let x = &s.1;
|
||||
witness(&x); // keep variable in an alloca
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue