Skip to content

Commit

Permalink
Merge pull request #519 from sadlerap/simd-ptr-provenance
Browse files Browse the repository at this point in the history
simd: implement pointer provenance intrinsics
  • Loading branch information
antoyo authored May 27, 2024
2 parents b13943e + a0b4d73 commit 02eb434
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 1 deletion.
135 changes: 135 additions & 0 deletions src/intrinsic/simd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,141 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
return Ok(bx.vector_select(args[0].immediate(), args[1].immediate(), args[2].immediate()));
}

if name == sym::simd_cast_ptr {
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());

require!(
in_len == out_len,
InvalidMonomorphization::ReturnLengthInputType {
span,
name,
in_len,
in_ty,
ret_ty,
out_len
}
);

match *in_elem.kind() {
ty::RawPtr(p) => {
let metadata = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
});
require!(
metadata.is_unit(),
InvalidMonomorphization::CastFatPointer { span, name, ty: in_elem }
);
}
_ => {
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
}
}
match *out_elem.kind() {
ty::RawPtr(p) => {
let metadata = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
});
require!(
metadata.is_unit(),
InvalidMonomorphization::CastFatPointer { span, name, ty: out_elem }
);
}
_ => {
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
}
}

let arg = args[0].immediate();
let elem_type = llret_ty.dyncast_vector().expect("vector return type").get_element_type();
let values: Vec<_> = (0..in_len)
.map(|i| {
let idx = bx.gcc_int(bx.usize_type, i as _);
let value = bx.extract_element(arg, idx);
bx.pointercast(value, elem_type)
})
.collect();
return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &values));
}

if name == sym::simd_expose_addr {
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());

require!(
in_len == out_len,
InvalidMonomorphization::ReturnLengthInputType {
span,
name,
in_len,
in_ty,
ret_ty,
out_len
}
);

match *in_elem.kind() {
ty::RawPtr(_) => {}
_ => {
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
}
}
match *out_elem.kind() {
ty::Uint(ty::UintTy::Usize) => {}
_ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: out_elem }),
}

let arg = args[0].immediate();
let elem_type = llret_ty.dyncast_vector().expect("vector return type").get_element_type();
let values: Vec<_> = (0..in_len)
.map(|i| {
let idx = bx.gcc_int(bx.usize_type, i as _);
let value = bx.extract_element(arg, idx);
bx.ptrtoint(value, elem_type)
})
.collect();
return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &values));
}

if name == sym::simd_from_exposed_addr {
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());

require!(
in_len == out_len,
InvalidMonomorphization::ReturnLengthInputType {
span,
name,
in_len,
in_ty,
ret_ty,
out_len
}
);

match *in_elem.kind() {
ty::Uint(ty::UintTy::Usize) => {}
_ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: in_elem }),
}
match *out_elem.kind() {
ty::RawPtr(_) => {}
_ => {
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
}
}

let arg = args[0].immediate();
let elem_type = llret_ty.dyncast_vector().expect("vector return type").get_element_type();
let values: Vec<_> = (0..in_len)
.map(|i| {
let idx = bx.gcc_int(bx.usize_type, i as _);
let value = bx.extract_element(arg, idx);
bx.inttoptr(value, elem_type)
})
.collect();
return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &values));
}

#[cfg(feature = "master")]
if name == sym::simd_cast || name == sym::simd_as {
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
Expand Down
1 change: 0 additions & 1 deletion tests/failing-ui-tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ tests/ui/panic-runtime/abort.rs
tests/ui/panic-runtime/link-to-abort.rs
tests/ui/unwind-no-uwtable.rs
tests/ui/parser/unclosed-delimiter-in-dep.rs
tests/ui/simd/intrinsic/ptr-cast.rs
tests/ui/consts/missing_span_in_backtrace.rs
tests/ui/drop/dynamic-drop.rs
tests/ui/issues/issue-40883.rs
Expand Down

0 comments on commit 02eb434

Please sign in to comment.