-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
use GEP inbounds for ZST and DST field offsets
For the former, it's fine for `inbounds` offsets to be one-past-the-end, so it's okay even if the ZST is the last field in the layout: > The base pointer has an in bounds address of an allocated object, > which means that it points into an allocated object, or to its end. https://llvm.org/docs/LangRef.html#getelementptr-instruction For the latter, even DST fields must always be inside the layout (or to its end for ZSTs), so using inbounds is also fine there.
- Loading branch information
1 parent
7606c13
commit 8ebd307
Showing
3 changed files
with
73 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
//! This file tests that we correctly generate GEP instructions for DST | ||
//! field offsets. | ||
//@ compile-flags: -C no-prepopulate-passes -Copt-level=0 | ||
|
||
#![crate_type = "lib"] | ||
|
||
use std::ptr::addr_of; | ||
|
||
// Hack to get the correct type for usize | ||
// CHECK: @helper([[USIZE:i[0-9]+]] %_1) | ||
#[no_mangle] | ||
pub fn helper(_: usize) { | ||
} | ||
|
||
struct Dst<T: ?Sized> { | ||
x: u32, | ||
y: u8, | ||
z: T, | ||
} | ||
|
||
// CHECK: @dst_dyn_trait_offset(ptr align {{[0-9]+}} [[DATA_PTR:%.+]], ptr align {{[0-9]+}} [[VTABLE_PTR:%.+]]) | ||
#[no_mangle] | ||
pub fn dst_dyn_trait_offset(s: &Dst<dyn Drop>) -> &dyn Drop { | ||
// The alignment of dyn trait is unknown, so we compute the offset based on align from the vtable. | ||
|
||
// CHECK: [[SIZE_PTR:%[0-9]+]] = getelementptr inbounds {{.+}} [[VTABLE_PTR]] | ||
// CHECK: load [[USIZE]], ptr [[SIZE_PTR]] | ||
// CHECK: [[ALIGN_PTR:%[0-9]+]] = getelementptr inbounds {{.+}} [[VTABLE_PTR]] | ||
// CHECK: load [[USIZE]], ptr [[ALIGN_PTR]] | ||
|
||
// CHECK: getelementptr inbounds i8, ptr [[DATA_PTR]] | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: ret | ||
&s.z | ||
} | ||
|
||
// CHECK-LABEL: @dst_slice_offset | ||
#[no_mangle] | ||
pub fn dst_slice_offset(s: &Dst<[u16]>) -> &[u16] { | ||
// The alignment of [u16] is known, so we generate a GEP directly. | ||
|
||
// CHECK: start: | ||
// CHECK-NEXT: getelementptr inbounds i8, {{.+}}, [[USIZE]] 6 | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: ret | ||
&s.z | ||
} | ||
|
||
#[repr(packed)] | ||
struct PackedDstSlice { | ||
x: u32, | ||
y: u8, | ||
z: [u16], | ||
} | ||
|
||
// CHECK-LABEL: @packed_dst_slice_offset | ||
#[no_mangle] | ||
pub fn packed_dst_slice_offset(s: &PackedDstSlice) -> *const [u16] { | ||
// The alignment of [u16] is known, so we generate a GEP directly. | ||
|
||
// CHECK: start: | ||
// CHECK-NEXT: getelementptr inbounds i8, {{.+}}, [[USIZE]] 5 | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: ret | ||
addr_of!(s.z) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters