Skip to content

Commit f57b9e6

Browse files
committed
Auto merge of #150564 - rwardd:rwardd/option_or_codegen_tests, r=scottmcm
Added codegen tests for different forms of `Option::or` Adds tests to check the output of the different ways of writing `Option::or` Fixes #124533
2 parents 7ecabfa + a2fcb0d commit f57b9e6

1 file changed

Lines changed: 174 additions & 0 deletions

File tree

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// Tests output of multiple permutations of `Option::or`
2+
//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
3+
4+
#![crate_type = "lib"]
5+
6+
use std::num::NonZero;
7+
8+
// CHECK-LABEL: @or_match_u8
9+
// CHECK-SAME: (i1{{.+}}%0, i8 %1, i1{{.+}}%optb.0, i8 %optb.1)
10+
#[no_mangle]
11+
pub fn or_match_u8(opta: Option<u8>, optb: Option<u8>) -> Option<u8> {
12+
// CHECK: start:
13+
// CHECK-DAG: [[A_OR_B:%.+]] = select i1 %0, i8 %1, i8 %optb.1
14+
// CHECK-DAG: [[IS_SOME:%.+]] = or i1 {{%0, %optb.0|%optb.0, %0}}
15+
// CHECK-NEXT: [[FLAG:%.+]] = insertvalue { i1, i8 } poison, i1 [[IS_SOME]], 0
16+
// CHECK-NEXT: [[R:%.+]] = insertvalue { i1, i8 } [[FLAG]], i8 [[A_OR_B]], 1
17+
// CHECK: ret { i1, i8 } [[R]]
18+
match opta {
19+
Some(x) => Some(x),
20+
None => optb,
21+
}
22+
}
23+
24+
// CHECK-LABEL: @or_match_alt_u8
25+
// CHECK-SAME: (i1{{.+}}%opta.0, i8 %opta.1, i1{{.+}}%optb.0, i8 %optb.1)
26+
#[no_mangle]
27+
pub fn or_match_alt_u8(opta: Option<u8>, optb: Option<u8>) -> Option<u8> {
28+
// CHECK: start:
29+
// CHECK-DAG: [[A_OR_B:%.+]] = select i1 %opta.0, i8 %opta.1, i8 %optb.1
30+
// CHECK-DAG: [[IS_SOME:%.+]] = or i1 {{%opta.0, %optb.0|%optb.0, %opta.0}}
31+
// CHECK-NEXT: [[FLAG:%.+]] = insertvalue { i1, i8 } poison, i1 [[IS_SOME]], 0
32+
// CHECK-NEXT: [[R:%.+]] = insertvalue { i1, i8 } [[FLAG]], i8 [[A_OR_B]], 1
33+
// CHECK: ret { i1, i8 } [[R]]
34+
match opta {
35+
Some(_) => opta,
36+
None => optb,
37+
}
38+
}
39+
40+
// CHECK-LABEL: @option_or_u8
41+
// CHECK-SAME: (i1{{.+}}%opta.0, i8 %opta.1, i1{{.+}}%optb.0, i8 %optb.1)
42+
#[no_mangle]
43+
pub fn option_or_u8(opta: Option<u8>, optb: Option<u8>) -> Option<u8> {
44+
// CHECK: start:
45+
// CHECK-DAG: [[A_OR_B:%.+]] = select i1 %opta.0, i8 %opta.1, i8 %optb.1
46+
// CHECK-DAG: [[IS_SOME:%.+]] = or i1 {{%opta.0, %optb.0|%optb.0, %opta.0}}
47+
// CHECK-NEXT: [[FLAG:%.+]] = insertvalue { i1, i8 } poison, i1 [[IS_SOME]], 0
48+
// CHECK-NEXT: [[R:%.+]] = insertvalue { i1, i8 } [[FLAG]], i8 [[A_OR_B]], 1
49+
// CHECK: ret { i1, i8 } [[R]]
50+
opta.or(optb)
51+
}
52+
53+
// CHECK-LABEL: @if_some_u8
54+
// CHECK-SAME: (i1{{.+}}%opta.0, i8 %opta.1, i1{{.+}}%optb.0, i8 %optb.1)
55+
#[no_mangle]
56+
pub fn if_some_u8(opta: Option<u8>, optb: Option<u8>) -> Option<u8> {
57+
// CHECK: start:
58+
// CHECK-DAG: [[A_OR_B:%.+]] = select i1 %opta.0, i8 %opta.1, i8 %optb.1
59+
// CHECK-DAG: [[IS_SOME:%.+]] = or i1 {{%opta.0, %optb.0|%optb.0, %opta.0}}
60+
// CHECK-NEXT: [[FLAG:%.+]] = insertvalue { i1, i8 } poison, i1 [[IS_SOME]], 0
61+
// CHECK-NEXT: [[R:%.+]] = insertvalue { i1, i8 } [[FLAG]], i8 [[A_OR_B]], 1
62+
// CHECK: ret { i1, i8 } [[R]]
63+
if opta.is_some() { opta } else { optb }
64+
}
65+
66+
// Tests a case where an input is a type that is represented as `BackendRepr::Memory`
67+
68+
// CHECK-LABEL: @or_match_slice_u8
69+
// CHECK-SAME: (i16 %0, i16 %1)
70+
#[no_mangle]
71+
pub fn or_match_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> {
72+
// CHECK: start:
73+
// CHECK-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1
74+
// CHECK-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1
75+
// CHECK: ret i16 [[R]]
76+
match opta {
77+
Some(x) => Some(x),
78+
None => optb,
79+
}
80+
}
81+
82+
// CHECK-LABEL: @or_match_slice_alt_u8
83+
// CHECK-SAME: (i16 %0, i16 %1)
84+
#[no_mangle]
85+
pub fn or_match_slice_alt_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> {
86+
// CHECK: start:
87+
// CHECK-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1
88+
// CHECK-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1
89+
// CHECK: ret i16 [[R]]
90+
match opta {
91+
Some(_) => opta,
92+
None => optb,
93+
}
94+
}
95+
96+
// CHECK-LABEL: @option_or_slice_u8
97+
// CHECK-SAME: (i16 %0, i16 %1)
98+
#[no_mangle]
99+
pub fn option_or_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> {
100+
// CHECK: start:
101+
// CHECK-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1
102+
// CHECK-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1
103+
// CHECK: ret i16 [[R]]
104+
opta.or(optb)
105+
}
106+
107+
// CHECK-LABEL: @if_some_slice_u8
108+
// CHECK-SAME: (i16 %0, i16 %1)
109+
#[no_mangle]
110+
pub fn if_some_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> {
111+
// CHECK: start:
112+
// CHECK-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1
113+
// CHECK-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1
114+
// CHECK: ret i16 [[R]]
115+
if opta.is_some() { opta } else { optb }
116+
}
117+
118+
// Test a niche optimization case of `NonZero<u8>`
119+
120+
// CHECK-LABEL: @or_match_nz_u8
121+
// CHECK-SAME: (i8{{.+}}%0, i8{{.+}}%optb)
122+
#[no_mangle]
123+
pub fn or_match_nz_u8(opta: Option<NonZero<u8>>, optb: Option<NonZero<u8>>) -> Option<NonZero<u8>> {
124+
// CHECK: start:
125+
// CHECK-NEXT: [[NOT_A:%.+]] = icmp eq i8 %0, 0
126+
// CHECK-NEXT: [[R:%.+]] = select i1 [[NOT_A]], i8 %optb, i8 %0
127+
// CHECK: ret i8 [[R]]
128+
match opta {
129+
Some(x) => Some(x),
130+
None => optb,
131+
}
132+
}
133+
134+
// CHECK-LABEL: @or_match_alt_nz_u8
135+
// CHECK-SAME: (i8{{.+}}%opta, i8{{.+}}%optb)
136+
#[no_mangle]
137+
pub fn or_match_alt_nz_u8(
138+
opta: Option<NonZero<u8>>,
139+
optb: Option<NonZero<u8>>,
140+
) -> Option<NonZero<u8>> {
141+
// CHECK: start:
142+
// CHECK-NEXT: [[NOT_A:%.+]] = icmp eq i8 %opta, 0
143+
// CHECK-NEXT: [[R:%.+]] = select i1 [[NOT_A]], i8 %optb, i8 %opta
144+
// CHECK: ret i8 [[R]]
145+
match opta {
146+
Some(_) => opta,
147+
None => optb,
148+
}
149+
}
150+
151+
// CHECK-LABEL: @option_or_nz_u8
152+
// CHECK-SAME: (i8{{.+}}%opta, i8{{.+}}%optb)
153+
#[no_mangle]
154+
pub fn option_or_nz_u8(
155+
opta: Option<NonZero<u8>>,
156+
optb: Option<NonZero<u8>>,
157+
) -> Option<NonZero<u8>> {
158+
// CHECK: start:
159+
// CHECK-NEXT: [[NOT_A:%.+]] = icmp eq i8 %opta, 0
160+
// CHECK-NEXT: [[R:%.+]] = select i1 [[NOT_A]], i8 %optb, i8 %opta
161+
// CHECK: ret i8 [[R]]
162+
opta.or(optb)
163+
}
164+
165+
// CHECK-LABEL: @if_some_nz_u8
166+
// CHECK-SAME: (i8{{.+}}%opta, i8{{.+}}%optb)
167+
#[no_mangle]
168+
pub fn if_some_nz_u8(opta: Option<NonZero<u8>>, optb: Option<NonZero<u8>>) -> Option<NonZero<u8>> {
169+
// CHECK: start:
170+
// CHECK-NEXT: [[NOT_A:%.+]] = icmp eq i8 %opta, 0
171+
// CHECK-NEXT: [[R:%.+]] = select i1 [[NOT_A]], i8 %optb, i8 %opta
172+
// CHECK: ret i8 [[R]]
173+
if opta.is_some() { opta } else { optb }
174+
}

0 commit comments

Comments
 (0)