Skip to content

Commit 02eb434

Browse files
authored
Merge pull request #519 from sadlerap/simd-ptr-provenance
simd: implement pointer provenance intrinsics
2 parents b13943e + a0b4d73 commit 02eb434

File tree

2 files changed

+135
-1
lines changed

2 files changed

+135
-1
lines changed

src/intrinsic/simd.rs

+135
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,141 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
434434
return Ok(bx.vector_select(args[0].immediate(), args[1].immediate(), args[2].immediate()));
435435
}
436436

437+
if name == sym::simd_cast_ptr {
438+
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
439+
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
440+
441+
require!(
442+
in_len == out_len,
443+
InvalidMonomorphization::ReturnLengthInputType {
444+
span,
445+
name,
446+
in_len,
447+
in_ty,
448+
ret_ty,
449+
out_len
450+
}
451+
);
452+
453+
match *in_elem.kind() {
454+
ty::RawPtr(p) => {
455+
let metadata = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
456+
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
457+
});
458+
require!(
459+
metadata.is_unit(),
460+
InvalidMonomorphization::CastFatPointer { span, name, ty: in_elem }
461+
);
462+
}
463+
_ => {
464+
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
465+
}
466+
}
467+
match *out_elem.kind() {
468+
ty::RawPtr(p) => {
469+
let metadata = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
470+
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
471+
});
472+
require!(
473+
metadata.is_unit(),
474+
InvalidMonomorphization::CastFatPointer { span, name, ty: out_elem }
475+
);
476+
}
477+
_ => {
478+
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
479+
}
480+
}
481+
482+
let arg = args[0].immediate();
483+
let elem_type = llret_ty.dyncast_vector().expect("vector return type").get_element_type();
484+
let values: Vec<_> = (0..in_len)
485+
.map(|i| {
486+
let idx = bx.gcc_int(bx.usize_type, i as _);
487+
let value = bx.extract_element(arg, idx);
488+
bx.pointercast(value, elem_type)
489+
})
490+
.collect();
491+
return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &values));
492+
}
493+
494+
if name == sym::simd_expose_addr {
495+
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
496+
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
497+
498+
require!(
499+
in_len == out_len,
500+
InvalidMonomorphization::ReturnLengthInputType {
501+
span,
502+
name,
503+
in_len,
504+
in_ty,
505+
ret_ty,
506+
out_len
507+
}
508+
);
509+
510+
match *in_elem.kind() {
511+
ty::RawPtr(_) => {}
512+
_ => {
513+
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
514+
}
515+
}
516+
match *out_elem.kind() {
517+
ty::Uint(ty::UintTy::Usize) => {}
518+
_ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: out_elem }),
519+
}
520+
521+
let arg = args[0].immediate();
522+
let elem_type = llret_ty.dyncast_vector().expect("vector return type").get_element_type();
523+
let values: Vec<_> = (0..in_len)
524+
.map(|i| {
525+
let idx = bx.gcc_int(bx.usize_type, i as _);
526+
let value = bx.extract_element(arg, idx);
527+
bx.ptrtoint(value, elem_type)
528+
})
529+
.collect();
530+
return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &values));
531+
}
532+
533+
if name == sym::simd_from_exposed_addr {
534+
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
535+
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
536+
537+
require!(
538+
in_len == out_len,
539+
InvalidMonomorphization::ReturnLengthInputType {
540+
span,
541+
name,
542+
in_len,
543+
in_ty,
544+
ret_ty,
545+
out_len
546+
}
547+
);
548+
549+
match *in_elem.kind() {
550+
ty::Uint(ty::UintTy::Usize) => {}
551+
_ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: in_elem }),
552+
}
553+
match *out_elem.kind() {
554+
ty::RawPtr(_) => {}
555+
_ => {
556+
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
557+
}
558+
}
559+
560+
let arg = args[0].immediate();
561+
let elem_type = llret_ty.dyncast_vector().expect("vector return type").get_element_type();
562+
let values: Vec<_> = (0..in_len)
563+
.map(|i| {
564+
let idx = bx.gcc_int(bx.usize_type, i as _);
565+
let value = bx.extract_element(arg, idx);
566+
bx.inttoptr(value, elem_type)
567+
})
568+
.collect();
569+
return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &values));
570+
}
571+
437572
#[cfg(feature = "master")]
438573
if name == sym::simd_cast || name == sym::simd_as {
439574
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });

tests/failing-ui-tests.txt

-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ tests/ui/panic-runtime/abort.rs
3333
tests/ui/panic-runtime/link-to-abort.rs
3434
tests/ui/unwind-no-uwtable.rs
3535
tests/ui/parser/unclosed-delimiter-in-dep.rs
36-
tests/ui/simd/intrinsic/ptr-cast.rs
3736
tests/ui/consts/missing_span_in_backtrace.rs
3837
tests/ui/drop/dynamic-drop.rs
3938
tests/ui/issues/issue-40883.rs

0 commit comments

Comments
 (0)