Auto merge of #94158 - erikdesjardins:more-more-noundef, r=nikic

Apply noundef metadata to loads of types that do not permit raw init

This matches the noundef attributes we apply on arguments/return types.

Fixes (partially) #74378.
This commit is contained in:
bors 2022-02-28 06:11:20 +00:00
commit 427cf81206
3 changed files with 98 additions and 4 deletions

View File

@ -479,6 +479,10 @@ fn scalar_load_metadata<'a, 'll, 'tcx>(
load: &'ll Value,
scalar: abi::Scalar,
) {
if !scalar.is_always_valid(bx) {
bx.noundef_metadata(load);
}
match scalar.value {
abi::Int(..) => {
if !scalar.is_always_valid(bx) {
@ -1215,6 +1219,16 @@ fn position_at_start(&mut self, llbb: &'ll BasicBlock) {
}
}
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 {
unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
}

View File

@ -442,6 +442,7 @@ pub enum MetadataType {
MD_mem_parallel_loop_access = 10,
MD_nonnull = 11,
MD_type = 19,
MD_noundef = 29,
}
/// LLVMRustAsmDialect

View File

@ -2,11 +2,87 @@
#![crate_type = "lib"]
use std::mem::MaybeUninit;
use std::num::NonZeroU16;
pub struct Bytes {
a: u8,
b: u8,
c: u8,
d: u8,
a: u8,
b: u8,
c: 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
@ -43,3 +119,6 @@ pub fn small_struct_alignment(x: Bytes) -> Bytes {
// CHECK: ret i32 [[VAR]]
x
}
// CHECK: ![[BOOL_RANGE]] = !{i8 0, i8 2}
// CHECK: ![[NONZEROU16_RANGE]] = !{i16 1, i16 0}