1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
//@ compile-flags: -C no-prepopulate-passes -Zmir-opt-level=0 -O
#![crate_type = "lib"]
use std::mem::MaybeUninit;
use std::num::NonZero;
pub struct Bytes {
a: u8,
b: u8,
c: u8,
d: u8,
}
#[derive(Copy, Clone)]
pub enum MyBool {
True,
False,
}
#[repr(align(16))]
pub struct Align16(u128);
// CHECK: @ptr_alignment_helper({{.*}}align [[PTR_ALIGNMENT:[0-9]+]]
#[no_mangle]
pub fn ptr_alignment_helper(x: &&()) {}
// CHECK-LABEL: @load_ref
#[no_mangle]
pub fn load_ref<'a>(x: &&'a i32) -> &'a i32 {
// CHECK: load ptr, ptr %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META:[0-9]+]], !noundef !{{[0-9]+}}
*x
}
// CHECK-LABEL: @load_ref_higher_alignment
#[no_mangle]
pub fn load_ref_higher_alignment<'a>(x: &&'a Align16) -> &'a Align16 {
// CHECK: load ptr, ptr %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META:[0-9]+]], !noundef !{{[0-9]+}}
*x
}
// CHECK-LABEL: @load_scalar_pair
#[no_mangle]
pub fn load_scalar_pair<'a>(x: &(&'a i32, &'a Align16)) -> (&'a i32, &'a Align16) {
// CHECK: load ptr, ptr %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}}
// CHECK: load ptr, ptr %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META]], !noundef !{{[0-9]+}}
*x
}
// CHECK-LABEL: @load_raw_pointer
#[no_mangle]
pub fn load_raw_pointer<'a>(x: &*const i32) -> *const i32 {
// loaded raw pointer should not have !nonnull or !align metadata
// CHECK: load ptr, ptr %x, align [[PTR_ALIGNMENT]], !noundef ![[NOUNDEF:[0-9]+]]{{$}}
*x
}
// CHECK-LABEL: @load_box
#[no_mangle]
pub fn load_box<'a>(x: Box<Box<i32>>) -> Box<i32> {
// CHECK: load ptr, ptr %{{.*}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}}
*x
}
// CHECK-LABEL: @load_bool
#[no_mangle]
pub fn load_bool(x: &bool) -> bool {
// CHECK: load i8, ptr %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, ptr %x, align 1{{$}}
*x
}
// CHECK-LABEL: @load_enum_bool
#[no_mangle]
pub fn load_enum_bool(x: &MyBool) -> MyBool {
// CHECK: load i8, ptr %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, ptr %x, align 1{{$}}
*x
}
// CHECK-LABEL: @load_int
#[no_mangle]
pub fn load_int(x: &u16) -> u16 {
// CHECK: load i16, ptr %x, align 2, !noundef ![[NOUNDEF]]{{$}}
*x
}
// CHECK-LABEL: @load_nonzero_int
#[no_mangle]
pub fn load_nonzero_int(x: &NonZero<u16>) -> NonZero<u16> {
// CHECK: load i16, ptr %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<NonZero<u16>>) -> Option<NonZero<u16>> {
// CHECK: load i16, ptr %x, align 2, !noundef ![[NOUNDEF]]{{$}}
*x
}
// CHECK-LABEL: @borrow
#[no_mangle]
pub fn borrow(x: &i32) -> &i32 {
// CHECK: load ptr, ptr %x{{.*}}, !nonnull
&x; // keep variable in an alloca
x
}
// CHECK-LABEL: @_box
#[no_mangle]
pub fn _box(x: Box<i32>) -> i32 {
// CHECK: load ptr, ptr %x{{.*}}, align [[PTR_ALIGNMENT]]
*x
}
// CHECK-LABEL: small_array_alignment
// The array is loaded as i32, but its alignment is lower, go with 1 byte to avoid target
// dependent alignment
#[no_mangle]
pub fn small_array_alignment(x: [i8; 4]) -> [i8; 4] {
// CHECK: [[VAR:%[0-9]+]] = load i32, ptr %{{.*}}, align 1
// CHECK: ret i32 [[VAR]]
x
}
// CHECK-LABEL: small_struct_alignment
// The struct is loaded as i32, but its alignment is lower, go with 1 byte to avoid target
// dependent alignment
#[no_mangle]
pub fn small_struct_alignment(x: Bytes) -> Bytes {
// CHECK: [[VAR:%[0-9]+]] = load i32, ptr %{{.*}}, align 1
// CHECK: ret i32 [[VAR]]
x
}
// CHECK-DAG: ![[BOOL_RANGE]] = !{i8 0, i8 2}
// CHECK-DAG: ![[NONZEROU16_RANGE]] = !{i16 1, i16 0}
// CHECK-DAG: ![[ALIGN_4_META]] = !{i64 4}
// CHECK-DAG: ![[ALIGN_16_META]] = !{i64 16}
|