Skip to content

Commit

Permalink
Auto merge of #134117 - DianQK:gep-i8, r=oli-obk
Browse files Browse the repository at this point in the history
Modifies the index instruction from `gep [0 x %Type]` to `gep %Type`

Fixes #133979.

This PR modifies the index instruction from `gep [0 x %Type]` to `gep %Type`, which is the same with pointer offset calculation.

This will help LLVM calculate various formats of GEP instructions. According to [[RFC] Replacing getelementptr with ptradd](https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699), we ultimately aim to canonicalize everything to `gep i8`. Based on the results from #134117 (comment), I think we still need to investigate some missing optimizations, so this PR is just a small step forward.

r? compiler
  • Loading branch information
bors committed Dec 15, 2024
2 parents 0894fb0 + 3fc506b commit a611773
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
5 changes: 1 addition & 4 deletions compiler/rustc_codegen_ssa/src/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,10 +422,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
layout.size
};

let llval = bx.inbounds_gep(bx.cx().backend_type(self.layout), self.val.llval, &[
bx.cx().const_usize(0),
llindex,
]);
let llval = bx.inbounds_gep(bx.cx().backend_type(layout), self.val.llval, &[llindex]);
let align = self.val.align.restrict_for_offset(offset);
PlaceValue::new_sized(llval, align).with_type(layout)
}
Expand Down
22 changes: 22 additions & 0 deletions tests/codegen/bounds-checking/gep-issue-133979.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//! Issue: <https://github.com/rust-lang/rust/issues/133979>
//! Check that bounds checking are eliminated.
//@ compile-flags: -Copt-level=2

#![crate_type = "lib"]

// CHECK-LABEL: @test(
#[no_mangle]
fn test(a: &[&[u8]]) -> u32 {
// CHECK-NOT: panic_bounds_check
a.iter()
.enumerate()
.map(|(y, b)| {
b.iter()
.enumerate()
.filter(|(_, c)| **c == b'A')
.map(|(x, _)| a[y][x] as u32)
.sum::<u32>()
})
.sum()
}
37 changes: 37 additions & 0 deletions tests/codegen/gep-index.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//! Check that index and offset use the same getelementptr format.
//@ revisions: NO-OPT OPT
//@[NO-OPT] compile-flags: -Copt-level=0
//@[OPT] compile-flags: -Copt-level=1

#![crate_type = "lib"]

struct Foo(i32, i32);

// CHECK-LABEL: @index_on_struct(
#[no_mangle]
fn index_on_struct(a: &[Foo], index: usize) -> &Foo {
// CHECK: getelementptr inbounds %Foo, ptr %a.0, {{i64|i32}} %index
&a[index]
}

// CHECK-LABEL: @offset_on_struct(
#[no_mangle]
fn offset_on_struct(a: *const Foo, index: usize) -> *const Foo {
// CHECK: getelementptr inbounds %Foo, ptr %a, {{i64|i32}} %index
unsafe { a.add(index) }
}

// CHECK-LABEL: @index_on_i32(
#[no_mangle]
fn index_on_i32(a: &[i32], index: usize) -> &i32 {
// CHECK: getelementptr inbounds i32, ptr %a.0, {{i64|i32}} %index
&a[index]
}

// CHECK-LABEL: @offset_on_i32(
#[no_mangle]
fn offset_on_i32(a: *const i32, index: usize) -> *const i32 {
// CHECK: getelementptr inbounds i32, ptr %a, {{i64|i32}} %index
unsafe { a.add(index) }
}

0 comments on commit a611773

Please sign in to comment.