Apply noundef metadata to loads of types that do not permit raw init
This matches the noundef attributes we apply on arguments/return types.
This commit is contained in:
parent
3b1fe7e7c9
commit
fec4335407
3 changed files with 98 additions and 4 deletions
|
@ -479,6 +479,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
load: &'ll Value,
|
load: &'ll Value,
|
||||||
scalar: abi::Scalar,
|
scalar: abi::Scalar,
|
||||||
) {
|
) {
|
||||||
|
if !scalar.is_always_valid(bx) {
|
||||||
|
bx.noundef_metadata(load);
|
||||||
|
}
|
||||||
|
|
||||||
match scalar.value {
|
match scalar.value {
|
||||||
abi::Int(..) => {
|
abi::Int(..) => {
|
||||||
if !scalar.is_always_valid(bx) {
|
if !scalar.is_always_valid(bx) {
|
||||||
|
@ -1215,6 +1219,16 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn noundef_metadata(&mut self, load: &'ll Value) {
|
||||||
|
unsafe {
|
||||||
|
llvm::LLVMSetMetadata(
|
||||||
|
load,
|
||||||
|
llvm::MD_noundef as c_uint,
|
||||||
|
llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
|
pub fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
|
unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -442,6 +442,7 @@ pub enum MetadataType {
|
||||||
MD_mem_parallel_loop_access = 10,
|
MD_mem_parallel_loop_access = 10,
|
||||||
MD_nonnull = 11,
|
MD_nonnull = 11,
|
||||||
MD_type = 19,
|
MD_type = 19,
|
||||||
|
MD_noundef = 29,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// LLVMRustAsmDialect
|
/// LLVMRustAsmDialect
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
|
use std::num::NonZeroU16;
|
||||||
|
|
||||||
pub struct Bytes {
|
pub struct Bytes {
|
||||||
a: u8,
|
a: u8,
|
||||||
b: u8,
|
b: u8,
|
||||||
|
@ -9,6 +12,79 @@ pub struct Bytes {
|
||||||
d: u8,
|
d: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub enum MyBool {
|
||||||
|
True,
|
||||||
|
False,
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @load_ref
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn load_ref<'a>(x: &&'a i32) -> &'a i32 {
|
||||||
|
// Alignment of a reference itself is target dependent, so just match any alignment:
|
||||||
|
// the main thing we care about here is !nonnull and !noundef.
|
||||||
|
// CHECK: load i32*, i32** %x, align {{[0-9]+}}, !nonnull !{{[0-9]+}}, !noundef !{{[0-9]+}}
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @load_box
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn load_box<'a>(x: Box<Box<i32>>) -> Box<i32> {
|
||||||
|
// Alignment of a box itself is target dependent, so just match any alignment:
|
||||||
|
// the main thing we care about here is !nonnull and !noundef.
|
||||||
|
// CHECK: load i32*, i32** %x, align {{[0-9]+}}, !nonnull !{{[0-9]+}}, !noundef !{{[0-9]+}}
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @load_bool
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn load_bool(x: &bool) -> bool {
|
||||||
|
// CHECK: load i8, i8* %x, align 1, !range ![[BOOL_RANGE:[0-9]+]], !noundef !{{[0-9]+}}
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @load_maybeuninit_bool
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn load_maybeuninit_bool(x: &MaybeUninit<bool>) -> MaybeUninit<bool> {
|
||||||
|
// CHECK: load i8, i8* %x, align 1{{$}}
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @load_enum_bool
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn load_enum_bool(x: &MyBool) -> MyBool {
|
||||||
|
// CHECK: load i8, i8* %x, align 1, !range ![[BOOL_RANGE]], !noundef !{{[0-9]+}}
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @load_maybeuninit_enum_bool
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn load_maybeuninit_enum_bool(x: &MaybeUninit<MyBool>) -> MaybeUninit<MyBool> {
|
||||||
|
// CHECK: load i8, i8* %x, align 1{{$}}
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @load_int
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn load_int(x: &u16) -> u16 {
|
||||||
|
// CHECK: load i16, i16* %x, align 2{{$}}
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @load_nonzero_int
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn load_nonzero_int(x: &NonZeroU16) -> NonZeroU16 {
|
||||||
|
// CHECK: load i16, i16* %x, align 2, !range ![[NONZEROU16_RANGE:[0-9]+]], !noundef !{{[0-9]+}}
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @load_option_nonzero_int
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn load_option_nonzero_int(x: &Option<NonZeroU16>) -> Option<NonZeroU16> {
|
||||||
|
// CHECK: load i16, i16* %x, align 2{{$}}
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: @borrow
|
// CHECK-LABEL: @borrow
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn borrow(x: &i32) -> &i32 {
|
pub fn borrow(x: &i32) -> &i32 {
|
||||||
|
@ -43,3 +119,6 @@ pub fn small_struct_alignment(x: Bytes) -> Bytes {
|
||||||
// CHECK: ret i32 [[VAR]]
|
// CHECK: ret i32 [[VAR]]
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK: ![[BOOL_RANGE]] = !{i8 0, i8 2}
|
||||||
|
// CHECK: ![[NONZEROU16_RANGE]] = !{i16 1, i16 0}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue