Skip to content

Commit

Permalink
Also emit noundef for #[repr(transparent)] structs/enums containi…
Browse files Browse the repository at this point in the history
…ng array immediate eligble arguments
  • Loading branch information
jieyouxu committed Apr 7, 2024
1 parent c0d727b commit f31e07f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
15 changes: 13 additions & 2 deletions compiler/rustc_ty_utils/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,8 +786,19 @@ fn fn_abi_adjust_for_abi<'tcx>(
arg.cast_to(Reg { kind: RegKind::Integer, size });

// Let's see if we can add a `noundef`. This is only legal for arrays, definitely
// not for unions.
if arg.layout.ty.is_array() {
// not for unions. This is also legal for `#[repr(transparent)] struct` or
// `#[repr(transparent)] enum` containing array.
let is_transparent_array =
if arg.layout.is_transparent::<LayoutCx<'tcx, TyCtxt<'tcx>>>()
&& let Some((_, layout)) = arg.layout.non_1zst_field(cx)
&& layout.ty.is_array()
{
true
} else {
false
};

if arg.layout.ty.is_array() || is_transparent_array {
// Fixup arg attribute with `noundef`.
let PassMode::Cast { ref mut cast, .. } = &mut arg.mode else {
bug!("this cannot fail because of the previous cast_to `Reg`");
Expand Down
20 changes: 20 additions & 0 deletions tests/codegen/array-immediate-param-noundef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,23 @@ pub fn replace_short_array_u8x3(r: &mut [u8; 3], v: [u8; 3]) -> [u8; 3] {
pub fn replace_short_array_u8x8(r: &mut [u8; 8], v: [u8; 8]) -> [u8; 8] {
std::mem::replace(r, v)
}

#[repr(transparent)]
pub struct Foo([u8; 4]);

// CHECK: define noundef i32 @replace_repr_transparent_struct_short_array(ptr noalias noundef align 1 dereferenceable(4) %r, i32 noundef %0)
#[no_mangle]
pub fn replace_repr_transparent_struct_short_array(r: &mut Foo, v: Foo) -> Foo {
std::mem::replace(r, v)
}

#[repr(transparent)]
pub enum Bar {
Default([u8; 4])
}

// CHECK: define noundef i32 @replace_repr_transparent_enum_short_array(ptr noalias noundef align 1 dereferenceable(4) %r, i32 noundef %0)
#[no_mangle]
pub fn replace_repr_transparent_enum_short_array(r: &mut Bar, v: Bar) -> Bar {
std::mem::replace(r, v)
}

0 comments on commit f31e07f

Please sign in to comment.