summaryrefslogtreecommitdiff
path: root/tests/mir-opt/lower_intrinsics.rs
blob: 0ca88a42e3fd05fef10c281bd6d618dd9cdf8ed1 (plain)
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
// unit-test: LowerIntrinsics
// ignore-wasm32 compiled with panic=abort by default

#![feature(core_intrinsics, intrinsics, rustc_attrs)]
#![crate_type = "lib"]

// EMIT_MIR lower_intrinsics.wrapping.LowerIntrinsics.diff
pub fn wrapping(a: i32, b: i32) {
    let _x = core::intrinsics::wrapping_add(a, b);
    let _y = core::intrinsics::wrapping_sub(a, b);
    let _z = core::intrinsics::wrapping_mul(a, b);
}

// EMIT_MIR lower_intrinsics.size_of.LowerIntrinsics.diff
pub fn size_of<T>() -> usize {
    core::intrinsics::size_of::<T>()
}

// EMIT_MIR lower_intrinsics.align_of.LowerIntrinsics.diff
pub fn align_of<T>() -> usize {
    core::intrinsics::min_align_of::<T>()
}

// EMIT_MIR lower_intrinsics.forget.LowerIntrinsics.diff
pub fn forget<T>(t: T) {
    core::intrinsics::forget(t)
}

// EMIT_MIR lower_intrinsics.unreachable.LowerIntrinsics.diff
pub fn unreachable() -> ! {
    unsafe { core::intrinsics::unreachable() };
}

// EMIT_MIR lower_intrinsics.non_const.LowerIntrinsics.diff
pub fn non_const<T>() -> usize {
    // Check that lowering works with non-const operand as a func.
    let size_of_t = core::intrinsics::size_of::<T>;
    size_of_t()
}

// EMIT_MIR lower_intrinsics.transmute_inhabited.LowerIntrinsics.diff
pub fn transmute_inhabited(c: std::cmp::Ordering) -> i8 {
    unsafe { std::mem::transmute(c) }
}

// EMIT_MIR lower_intrinsics.transmute_uninhabited.LowerIntrinsics.diff
pub unsafe fn transmute_uninhabited(u: ()) -> Never {
    unsafe { std::mem::transmute::<(), Never>(u) }
}

// EMIT_MIR lower_intrinsics.transmute_ref_dst.LowerIntrinsics.diff
pub unsafe fn transmute_ref_dst<T: ?Sized>(u: &T) -> *const T {
    unsafe { std::mem::transmute(u) }
}

// EMIT_MIR lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.diff
pub unsafe fn transmute_to_ref_uninhabited() -> ! {
    let x: &Never = std::mem::transmute(1usize);
    match *x {}
}

// EMIT_MIR lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.diff
pub unsafe fn transmute_to_mut_uninhabited() -> ! {
    let x: &mut Never = std::mem::transmute(1usize);
    match *x {}
}

// EMIT_MIR lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.diff
pub unsafe fn transmute_to_box_uninhabited() -> ! {
    let x: Box<Never> = std::mem::transmute(1usize);
    match *x {}
}

pub enum E {
    A,
    B,
    C,
}

// EMIT_MIR lower_intrinsics.discriminant.LowerIntrinsics.diff
pub fn discriminant<T>(t: T) {
    core::intrinsics::discriminant_value(&t);
    core::intrinsics::discriminant_value(&0);
    core::intrinsics::discriminant_value(&());
    core::intrinsics::discriminant_value(&E::B);
}

extern "rust-intrinsic" {
    // Cannot use `std::intrinsics::copy_nonoverlapping` as that is a wrapper function
    #[rustc_nounwind]
    fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
}

// EMIT_MIR lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff
pub fn f_copy_nonoverlapping() {
    let src = ();
    let mut dst = ();
    unsafe {
        copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0);
    }
}

// EMIT_MIR lower_intrinsics.assume.LowerIntrinsics.diff
pub fn assume() {
    unsafe {
        std::intrinsics::assume(true);
    }
}

// EMIT_MIR lower_intrinsics.with_overflow.LowerIntrinsics.diff
pub fn with_overflow(a: i32, b: i32) {
    let _x = core::intrinsics::add_with_overflow(a, b);
    let _y = core::intrinsics::sub_with_overflow(a, b);
    let _z = core::intrinsics::mul_with_overflow(a, b);
}

// EMIT_MIR lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.diff
pub fn read_via_copy_primitive(r: &i32) -> i32 {
    unsafe { core::intrinsics::read_via_copy(r) }
}

// EMIT_MIR lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff
pub fn read_via_copy_uninhabited(r: &Never) -> Never {
    unsafe { core::intrinsics::read_via_copy(r) }
}

// EMIT_MIR lower_intrinsics.write_via_move_string.LowerIntrinsics.diff
pub fn write_via_move_string(r: &mut String, v: String) {
    unsafe { core::intrinsics::write_via_move(r, v) }
}

pub enum Never {}

// EMIT_MIR lower_intrinsics.option_payload.LowerIntrinsics.diff
pub fn option_payload(o: &Option<usize>, p: &Option<String>) {
    unsafe {
        let _x = core::intrinsics::option_payload_ptr(o);
        let _y = core::intrinsics::option_payload_ptr(p);
    }
}

// EMIT_MIR lower_intrinsics.ptr_offset.LowerIntrinsics.diff
pub unsafe fn ptr_offset(p: *const i32, d: isize) -> *const i32 {
    core::intrinsics::offset(p, d)
}