1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 define i32 @max_na_b_minux_na(i32 %A, i32 %B) {
5 ; CHECK-LABEL: @max_na_b_minux_na(
6 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
7 ; CHECK-NEXT: [[L0:%.*]] = icmp ult i32 [[NOT]], [[B:%.*]]
8 ; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 [[B]]
9 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[L1]], [[NOT]]
10 ; CHECK-NEXT: ret i32 [[X]]
13 %l0 = icmp ult i32 %not, %B
14 %l1 = select i1 %l0, i32 %not, i32 %B
15 %x = sub i32 %l1, %not
19 define i32 @na_minus_max_na_b(i32 %A, i32 %B) {
20 ; CHECK-LABEL: @na_minus_max_na_b(
21 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
22 ; CHECK-NEXT: [[L0:%.*]] = icmp ult i32 [[NOT]], [[B:%.*]]
23 ; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 [[B]]
24 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[NOT]], [[L1]]
25 ; CHECK-NEXT: ret i32 [[X]]
28 %l0 = icmp ult i32 %not, %B
29 %l1 = select i1 %l0, i32 %not, i32 %B
30 %x = sub i32 %not, %l1
34 define i32 @max_b_na_minus_na(i32 %A, i32 %B) {
35 ; CHECK-LABEL: @max_b_na_minus_na(
36 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
37 ; CHECK-NEXT: [[L0:%.*]] = icmp ugt i32 [[NOT]], [[B:%.*]]
38 ; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[B]], i32 [[NOT]]
39 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[L1]], [[NOT]]
40 ; CHECK-NEXT: ret i32 [[X]]
43 %l0 = icmp ugt i32 %not, %B
44 %l1 = select i1 %l0, i32 %B, i32 %not
45 %x = sub i32 %l1, %not
49 define i32 @na_minus_max_b_na(i32 %A, i32 %B) {
50 ; CHECK-LABEL: @na_minus_max_b_na(
51 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
52 ; CHECK-NEXT: [[L0:%.*]] = icmp ugt i32 [[NOT]], [[B:%.*]]
53 ; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[B]], i32 [[NOT]]
54 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[NOT]], [[L1]]
55 ; CHECK-NEXT: ret i32 [[X]]
58 %l0 = icmp ugt i32 %not, %B
59 %l1 = select i1 %l0, i32 %B, i32 %not
60 %x = sub i32 %not, %l1
65 define i32 @max_na_bi_minux_na(i32 %A, i32 %Bi) {
66 ; CHECK-LABEL: @max_na_bi_minux_na(
67 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], [[BI:%.*]]
68 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
69 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[A]], [[TMP2]]
70 ; CHECK-NEXT: ret i32 [[X]]
74 %l0 = icmp ult i32 %not, %B
75 %l1 = select i1 %l0, i32 %not, i32 %B
76 %x = sub i32 %l1, %not
80 define i32 @na_minus_max_na_bi(i32 %A, i32 %Bi) {
81 ; CHECK-LABEL: @na_minus_max_na_bi(
82 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], [[BI:%.*]]
83 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
84 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[TMP2]], [[A]]
85 ; CHECK-NEXT: ret i32 [[X]]
89 %l0 = icmp ult i32 %not, %B
90 %l1 = select i1 %l0, i32 %not, i32 %B
91 %x = sub i32 %not, %l1
95 define i32 @max_bi_na_minus_na(i32 %A, i32 %Bi) {
96 ; CHECK-LABEL: @max_bi_na_minus_na(
97 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], [[BI:%.*]]
98 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
99 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[A]], [[TMP2]]
100 ; CHECK-NEXT: ret i32 [[X]]
103 %not = xor i32 %A, -1
104 %l0 = icmp ugt i32 %not, %B
105 %l1 = select i1 %l0, i32 %B, i32 %not
106 %x = sub i32 %l1, %not
110 define i32 @na_minus_max_bi_na(i32 %A, i32 %Bi) {
111 ; CHECK-LABEL: @na_minus_max_bi_na(
112 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], [[BI:%.*]]
113 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
114 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[TMP2]], [[A]]
115 ; CHECK-NEXT: ret i32 [[X]]
118 %not = xor i32 %A, -1
119 %l0 = icmp ugt i32 %not, %B
120 %l1 = select i1 %l0, i32 %B, i32 %not
121 %x = sub i32 %not, %l1
126 define i32 @max_na_bi_minux_na_use(i32 %A, i32 %Bi) {
127 ; CHECK-LABEL: @max_na_bi_minux_na_use(
128 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], -32
129 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 -32
130 ; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1
131 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[A]], [[TMP2]]
132 ; CHECK-NEXT: call void @use32(i32 [[L1]])
133 ; CHECK-NEXT: ret i32 [[X]]
135 %not = xor i32 %A, -1
136 %l0 = icmp ult i32 %not, 31
137 %l1 = select i1 %l0, i32 %not, i32 31
138 %x = sub i32 %l1, %not
139 call void @use32(i32 %l1)
143 define i32 @na_minus_max_na_bi_use(i32 %A, i32 %Bi) {
144 ; CHECK-LABEL: @na_minus_max_na_bi_use(
145 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], -32
146 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 -32
147 ; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1
148 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[TMP2]], [[A]]
149 ; CHECK-NEXT: call void @use32(i32 [[L1]])
150 ; CHECK-NEXT: ret i32 [[X]]
152 %not = xor i32 %A, -1
153 %l0 = icmp ult i32 %not, 31
154 %l1 = select i1 %l0, i32 %not, i32 31
155 %x = sub i32 %not, %l1
156 call void @use32(i32 %l1)
160 define i32 @max_bi_na_minus_na_use(i32 %A, i32 %Bi) {
161 ; CHECK-LABEL: @max_bi_na_minus_na_use(
162 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], [[BI:%.*]]
163 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
164 ; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1
165 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[A]], [[TMP2]]
166 ; CHECK-NEXT: call void @use32(i32 [[L1]])
167 ; CHECK-NEXT: ret i32 [[X]]
169 %not = xor i32 %A, -1
171 %l0 = icmp ult i32 %B, %not
172 %l1 = select i1 %l0, i32 %B, i32 %not
173 %x = sub i32 %l1, %not
174 call void @use32(i32 %l1)
178 define i32 @na_minus_max_bi_na_use(i32 %A, i32 %Bi) {
179 ; CHECK-LABEL: @na_minus_max_bi_na_use(
180 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], [[BI:%.*]]
181 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
182 ; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1
183 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[TMP2]], [[A]]
184 ; CHECK-NEXT: call void @use32(i32 [[L1]])
185 ; CHECK-NEXT: ret i32 [[X]]
187 %not = xor i32 %A, -1
189 %l0 = icmp ult i32 %B, %not
190 %l1 = select i1 %l0, i32 %B, i32 %not
191 %x = sub i32 %not, %l1
192 call void @use32(i32 %l1)
197 define i32 @max_na_bi_minux_na_use2(i32 %A, i32 %Bi) {
198 ; CHECK-LABEL: @max_na_bi_minux_na_use2(
199 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
200 ; CHECK-NEXT: [[L0:%.*]] = icmp ult i32 [[NOT]], 31
201 ; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 31
202 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[L1]], [[NOT]]
203 ; CHECK-NEXT: call void @use32(i32 [[L1]])
204 ; CHECK-NEXT: call void @use32(i32 [[NOT]])
205 ; CHECK-NEXT: ret i32 [[X]]
207 %not = xor i32 %A, -1
208 %l0 = icmp ult i32 %not, 31
209 %l1 = select i1 %l0, i32 %not, i32 31
210 %x = sub i32 %l1, %not
211 call void @use32(i32 %l1)
212 call void @use32(i32 %not)
216 define i32 @na_minus_max_na_bi_use2(i32 %A, i32 %Bi) {
217 ; CHECK-LABEL: @na_minus_max_na_bi_use2(
218 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
219 ; CHECK-NEXT: [[L0:%.*]] = icmp ult i32 [[NOT]], 31
220 ; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 31
221 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[NOT]], [[L1]]
222 ; CHECK-NEXT: call void @use32(i32 [[L1]])
223 ; CHECK-NEXT: call void @use32(i32 [[NOT]])
224 ; CHECK-NEXT: ret i32 [[X]]
226 %not = xor i32 %A, -1
227 %l0 = icmp ult i32 %not, 31
228 %l1 = select i1 %l0, i32 %not, i32 31
229 %x = sub i32 %not, %l1
230 call void @use32(i32 %l1)
231 call void @use32(i32 %not)
235 define i32 @max_bi_na_minus_na_use2(i32 %A, i32 %Bi) {
236 ; CHECK-LABEL: @max_bi_na_minus_na_use2(
237 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
238 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A]], [[BI:%.*]]
239 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
240 ; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1
241 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[A]], [[TMP2]]
242 ; CHECK-NEXT: call void @use32(i32 [[L1]])
243 ; CHECK-NEXT: call void @use32(i32 [[NOT]])
244 ; CHECK-NEXT: ret i32 [[X]]
246 %not = xor i32 %A, -1
248 %l0 = icmp ult i32 %B, %not
249 %l1 = select i1 %l0, i32 %B, i32 %not
250 %x = sub i32 %l1, %not
251 call void @use32(i32 %l1)
252 call void @use32(i32 %not)
256 define i32 @na_minus_max_bi_na_use2(i32 %A, i32 %Bi) {
257 ; CHECK-LABEL: @na_minus_max_bi_na_use2(
258 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
259 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A]], [[BI:%.*]]
260 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
261 ; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1
262 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[TMP2]], [[A]]
263 ; CHECK-NEXT: call void @use32(i32 [[L1]])
264 ; CHECK-NEXT: call void @use32(i32 [[NOT]])
265 ; CHECK-NEXT: ret i32 [[X]]
267 %not = xor i32 %A, -1
269 %l0 = icmp ult i32 %B, %not
270 %l1 = select i1 %l0, i32 %B, i32 %not
271 %x = sub i32 %not, %l1
272 call void @use32(i32 %l1)
273 call void @use32(i32 %not)
277 define i8 @umin_not_sub(i8 %x, i8 %y) {
278 ; CHECK-LABEL: @umin_not_sub(
279 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[Y:%.*]], [[X:%.*]]
280 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Y]]
281 ; CHECK-NEXT: [[MINXY:%.*]] = xor i8 [[TMP2]], -1
282 ; CHECK-NEXT: [[SUBX:%.*]] = sub i8 [[TMP2]], [[X]]
283 ; CHECK-NEXT: [[SUBY:%.*]] = sub i8 [[TMP2]], [[Y]]
284 ; CHECK-NEXT: call void @use8(i8 [[SUBX]])
285 ; CHECK-NEXT: call void @use8(i8 [[SUBY]])
286 ; CHECK-NEXT: ret i8 [[MINXY]]
290 %cmpxy = icmp ult i8 %nx, %ny
291 %minxy = select i1 %cmpxy, i8 %nx, i8 %ny
292 %subx = sub i8 %nx, %minxy
293 %suby = sub i8 %ny, %minxy
294 call void @use8(i8 %subx)
295 call void @use8(i8 %suby)
299 define i8 @umin_not_sub_rev(i8 %x, i8 %y) {
300 ; CHECK-LABEL: @umin_not_sub_rev(
301 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[Y:%.*]], [[X:%.*]]
302 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Y]]
303 ; CHECK-NEXT: [[MINXY:%.*]] = xor i8 [[TMP2]], -1
304 ; CHECK-NEXT: [[SUBX:%.*]] = sub i8 [[X]], [[TMP2]]
305 ; CHECK-NEXT: [[SUBY:%.*]] = sub i8 [[Y]], [[TMP2]]
306 ; CHECK-NEXT: call void @use8(i8 [[SUBX]])
307 ; CHECK-NEXT: call void @use8(i8 [[SUBY]])
308 ; CHECK-NEXT: ret i8 [[MINXY]]
312 %cmpxy = icmp ult i8 %nx, %ny
313 %minxy = select i1 %cmpxy, i8 %nx, i8 %ny
314 %subx = sub i8 %minxy, %nx
315 %suby = sub i8 %minxy, %ny
316 call void @use8(i8 %subx)
317 call void @use8(i8 %suby)
321 define void @umin3_not_all_ops_extra_uses_invert_subs(i8 %x, i8 %y, i8 %z) {
322 ; CHECK-LABEL: @umin3_not_all_ops_extra_uses_invert_subs(
323 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], [[Z:%.*]]
324 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Z]]
325 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i8 [[TMP2]], [[Y:%.*]]
326 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[Y]]
327 ; CHECK-NEXT: [[TMP5:%.*]] = xor i8 [[TMP4]], -1
328 ; CHECK-NEXT: [[XMIN:%.*]] = sub i8 [[TMP4]], [[X]]
329 ; CHECK-NEXT: [[YMIN:%.*]] = sub i8 [[TMP4]], [[Y]]
330 ; CHECK-NEXT: [[ZMIN:%.*]] = sub i8 [[TMP4]], [[Z]]
331 ; CHECK-NEXT: call void @use8(i8 [[TMP5]])
332 ; CHECK-NEXT: call void @use8(i8 [[XMIN]])
333 ; CHECK-NEXT: call void @use8(i8 [[YMIN]])
334 ; CHECK-NEXT: call void @use8(i8 [[ZMIN]])
335 ; CHECK-NEXT: ret void
340 %cmpxz = icmp ult i8 %xn, %zn
341 %minxz = select i1 %cmpxz, i8 %xn, i8 %zn
342 %cmpxyz = icmp ult i8 %minxz, %yn
343 %minxyz = select i1 %cmpxyz, i8 %minxz, i8 %yn
344 %xmin = sub i8 %xn, %minxyz
345 %ymin = sub i8 %yn, %minxyz
346 %zmin = sub i8 %zn, %minxyz
347 call void @use8(i8 %minxyz)
348 call void @use8(i8 %xmin)
349 call void @use8(i8 %ymin)
350 call void @use8(i8 %zmin)
354 declare void @use8(i8)
355 declare void @use32(i32 %u)