diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index f5cda81f6ab86..d93c774728543 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -14,7 +14,7 @@ use rustc_codegen_ssa::common::{ use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::{ - BackendTypes, BaseTypeMethods, BuilderMethods, ConstMethods, HasCodegen, LayoutTypeMethods, + BackendTypes, BaseTypeMethods, BuilderMethods, ConstMethods, HasCodegen, OverflowOp, StaticBuilderMethods, }; use rustc_codegen_ssa::MemFlags; @@ -1067,7 +1067,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { cg_elem.val.store(self, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align)); let next = self.inbounds_gep( - self.backend_type(cg_elem.layout), + self.type_array(self.type_i8(), cg_elem.layout.size.bytes()), current.to_rvalue(), &[self.const_usize(1)], ); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 467e02d55e332..99e9212686715 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -2378,7 +2378,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } let offsets = args[1].immediate(); - return Ok(bx.gep(bx.backend_type(layout), ptrs, &[offsets])); + let elem_sized_type = bx.type_array(bx.type_i8(), layout.size.bytes()); + return Ok(bx.gep(elem_sized_type, ptrs, &[offsets])); } if name == sym::simd_saturating_add || name == sym::simd_saturating_sub { diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 82488829b6e16..803e644913743 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -139,7 +139,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = bx.layout_of(ty); let ptr = args[0].immediate(); let offset = args[1].immediate(); - bx.gep(bx.backend_type(layout), ptr, &[offset]) + let elem_sized_type = bx.type_array(bx.type_i8(), layout.size.bytes()); + bx.gep(elem_sized_type, ptr, &[offset]) } sym::copy => { copy_intrinsic( diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 1ec6c351e2537..a38d6162d8ac7 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -356,12 +356,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { layout.size }; + let elem_sized_type = bx.type_array(bx.type_i8(), layout.size.bytes()); PlaceRef { - llval: bx.inbounds_gep( - bx.cx().backend_type(self.layout), - self.llval, - &[bx.cx().const_usize(0), llindex], - ), + llval: bx.inbounds_gep(elem_sized_type, self.llval, &[llindex]), llextra: None, layout, align: self.align.restrict_for_offset(offset), diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 8c6b9faf39d3e..12e6ad6101b7f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -862,8 +862,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // so offsetting a pointer to ZST is a noop. lhs } else { - let llty = bx.cx().backend_type(pointee_layout); - bx.inbounds_gep(llty, lhs, &[rhs]) + let elem_sized_type = bx.type_array(bx.type_i8(), pointee_layout.size.bytes()); + bx.inbounds_gep(elem_sized_type, lhs, &[rhs]) } } mir::BinOp::Shl => common::build_masked_lshift(bx, lhs, rhs), diff --git a/tests/codegen/intrinsics/arith_offset.rs b/tests/codegen/intrinsics/arith_offset.rs new file mode 100644 index 0000000000000..63711dd685c18 --- /dev/null +++ b/tests/codegen/intrinsics/arith_offset.rs @@ -0,0 +1,33 @@ +//@ compile-flags: -O + +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +use std::intrinsics::arith_offset; + +// CHECK-LABEL: ptr @arith_offset_zst +// CHECK-SAME: (ptr noundef{{.*}} %p, [[SIZE:i[0-9]+]] noundef %d) +#[no_mangle] +pub unsafe fn arith_offset_zst(p: *const (), d: isize) -> *const () { + // CHECK-NOT: getelementptr + // CHECK: ret ptr %p + arith_offset(p, d) +} + +// CHECK-LABEL: ptr @arith_offset_u32 +// CHECK-SAME: (ptr noundef{{.*}} %p, [[SIZE]] noundef %d) +#[no_mangle] +pub unsafe fn arith_offset_u32(p: *const u32, d: isize) -> *const u32 { + // CHECK: %[[R:.*]] = getelementptr [4 x i8], ptr %p, [[SIZE]] %d + // CHECK-NEXT: ret ptr %[[R]] + arith_offset(p, d) +} + +// CHECK-LABEL: ptr @arith_offset_u64 +// CHECK-SAME: (ptr noundef{{.*}} %p, [[SIZE]] noundef %d) +#[no_mangle] +pub unsafe fn arith_offset_u64(p: *const u64, d: isize) -> *const u64 { + // CHECK: %[[R:.*]] = getelementptr [8 x i8], ptr %p, [[SIZE]] %d + // CHECK-NEXT: ret ptr %[[R]] + arith_offset(p, d) +} diff --git a/tests/codegen/intrinsics/offset.rs b/tests/codegen/intrinsics/offset.rs index d4791cd30b0be..ba06e270bd1de 100644 --- a/tests/codegen/intrinsics/offset.rs +++ b/tests/codegen/intrinsics/offset.rs @@ -18,7 +18,7 @@ pub unsafe fn offset_zst(p: *const (), d: usize) -> *const () { // CHECK-SAME: (ptr noundef %p, [[SIZE]] noundef %d) #[no_mangle] pub unsafe fn offset_isize(p: *const u32, d: isize) -> *const u32 { - // CHECK: %[[R:.*]] = getelementptr inbounds i32, ptr %p, [[SIZE]] %d + // CHECK: %[[R:.*]] = getelementptr inbounds [4 x i8], ptr %p, [[SIZE]] %d // CHECK-NEXT: ret ptr %[[R]] offset(p, d) } @@ -27,7 +27,7 @@ pub unsafe fn offset_isize(p: *const u32, d: isize) -> *const u32 { // CHECK-SAME: (ptr noundef %p, [[SIZE]] noundef %d) #[no_mangle] pub unsafe fn offset_usize(p: *const u64, d: usize) -> *const u64 { - // CHECK: %[[R:.*]] = getelementptr inbounds i64, ptr %p, [[SIZE]] %d + // CHECK: %[[R:.*]] = getelementptr inbounds [8 x i8], ptr %p, [[SIZE]] %d // CHECK-NEXT: ret ptr %[[R]] offset(p, d) } diff --git a/tests/codegen/ptr-arithmetic.rs b/tests/codegen/ptr-arithmetic.rs index 6f115d33d8ddf..90185360e847c 100644 --- a/tests/codegen/ptr-arithmetic.rs +++ b/tests/codegen/ptr-arithmetic.rs @@ -6,7 +6,7 @@ // CHECK-SAME: [[WORD:i[0-9]+]] noundef %n) #[no_mangle] pub unsafe fn i32_add(p: *const i32, n: usize) -> *const i32 { - // CHECK: %[[TEMP:.+]] = getelementptr inbounds i32, ptr %p, [[WORD]] %n + // CHECK: %[[TEMP:.+]] = getelementptr inbounds [4 x i8], ptr %p, [[WORD]] %n // CHECK: ret ptr %[[TEMP]] p.add(n) } @@ -18,7 +18,7 @@ pub unsafe fn i32_add(p: *const i32, n: usize) -> *const i32 { #[no_mangle] pub unsafe fn i32_sub(p: *const i32, n: usize) -> *const i32 { // CHECK: %[[DELTA:.+]] = sub nsw [[WORD]] 0, %n - // CHECK: %[[TEMP:.+]] = getelementptr inbounds i32, ptr %p, [[WORD]] %[[DELTA]] + // CHECK: %[[TEMP:.+]] = getelementptr inbounds [4 x i8], ptr %p, [[WORD]] %[[DELTA]] // CHECK: ret ptr %[[TEMP]] p.sub(n) } @@ -27,7 +27,7 @@ pub unsafe fn i32_sub(p: *const i32, n: usize) -> *const i32 { // CHECK-SAME: [[WORD:i[0-9]+]] noundef %d) #[no_mangle] pub unsafe fn i32_offset(p: *const i32, d: isize) -> *const i32 { - // CHECK: %[[TEMP:.+]] = getelementptr inbounds i32, ptr %p, [[WORD]] %d + // CHECK: %[[TEMP:.+]] = getelementptr inbounds [4 x i8], ptr %p, [[WORD]] %d // CHECK: ret ptr %[[TEMP]] p.offset(d) } diff --git a/tests/codegen/simd/simd_arith_offset.rs b/tests/codegen/simd/simd_arith_offset.rs index e14fce1d41870..5b45bd21e47fa 100644 --- a/tests/codegen/simd/simd_arith_offset.rs +++ b/tests/codegen/simd/simd_arith_offset.rs @@ -18,9 +18,16 @@ pub struct SimdConstPtr([*const T; LANES]); #[repr(simd)] pub struct Simd([T; LANES]); -// CHECK-LABEL: smoke +// CHECK-LABEL: u8_offset #[no_mangle] -pub fn smoke(ptrs: SimdConstPtr, offsets: Simd) -> SimdConstPtr { - // CHECK: getelementptr i8, <8 x ptr> %0, <8 x i64> %1 +pub fn u8_offset(ptrs: SimdConstPtr, offsets: Simd) -> SimdConstPtr { + // CHECK: getelementptr [1 x i8], <8 x ptr> %0, <8 x i64> %1 + unsafe { simd_arith_offset(ptrs, offsets) } +} + +// CHECK-LABEL: u64_offset +#[no_mangle] +pub fn u64_offset(ptrs: SimdConstPtr, offsets: Simd) -> SimdConstPtr { + // CHECK: getelementptr [8 x i8], <8 x ptr> %0, <8 x i64> %1 unsafe { simd_arith_offset(ptrs, offsets) } } diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs index c960688b00c18..617389a6e0a00 100644 --- a/tests/codegen/slice-iter-nonnull.rs +++ b/tests/codegen/slice-iter-nonnull.rs @@ -54,7 +54,7 @@ pub fn slice_iter_next_back<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&' #[no_mangle] pub fn slice_iter_new(slice: &[u32]) -> std::slice::Iter<'_, u32> { // CHECK-NOT: slice - // CHECK: %[[END:.+]] = getelementptr inbounds i32{{.+}} %slice.0{{.+}} %slice.1 + // CHECK: %[[END:.+]] = getelementptr inbounds [4 x i8]{{.+}} %slice.0{{.+}} %slice.1 // CHECK-NOT: slice // CHECK: insertvalue {{.+}} ptr %slice.0, 0 // CHECK-NOT: slice @@ -69,7 +69,7 @@ pub fn slice_iter_new(slice: &[u32]) -> std::slice::Iter<'_, u32> { #[no_mangle] pub fn slice_iter_mut_new(slice: &mut [u32]) -> std::slice::IterMut<'_, u32> { // CHECK-NOT: slice - // CHECK: %[[END:.+]] = getelementptr inbounds i32{{.+}} %slice.0{{.+}} %slice.1 + // CHECK: %[[END:.+]] = getelementptr inbounds [4 x i8]{{.+}} %slice.0{{.+}} %slice.1 // CHECK-NOT: slice // CHECK: insertvalue {{.+}} ptr %slice.0, 0 // CHECK-NOT: slice