• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4define 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:    [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[NOT]], i32 [[B:%.*]])
8; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 0, [[TMP1]]
9; CHECK-NEXT:    ret i32 [[TMP2]]
10;
11  %not = xor i32 %A, -1
12  %l0 = icmp ult i32 %not, %B
13  %l1 = select i1 %l0, i32 %not, i32 %B
14  %x = sub i32 %l1, %not
15  ret i32 %x
16}
17
18define i32 @na_minus_max_na_b(i32 %A, i32 %B) {
19; CHECK-LABEL: @na_minus_max_na_b(
20; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
21; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[NOT]], i32 [[B:%.*]])
22; CHECK-NEXT:    ret i32 [[TMP1]]
23;
24  %not = xor i32 %A, -1
25  %l0 = icmp ult i32 %not, %B
26  %l1 = select i1 %l0, i32 %not, i32 %B
27  %x = sub i32 %not, %l1
28  ret i32 %x
29}
30
31define i32 @max_b_na_minus_na(i32 %A, i32 %B) {
32; CHECK-LABEL: @max_b_na_minus_na(
33; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
34; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[NOT]], i32 [[B:%.*]])
35; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 0, [[TMP1]]
36; CHECK-NEXT:    ret i32 [[TMP2]]
37;
38  %not = xor i32 %A, -1
39  %l0 = icmp ugt i32 %not, %B
40  %l1 = select i1 %l0, i32 %B, i32 %not
41  %x = sub i32 %l1, %not
42  ret i32 %x
43}
44
45define i32 @na_minus_max_b_na(i32 %A, i32 %B) {
46; CHECK-LABEL: @na_minus_max_b_na(
47; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
48; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[NOT]], i32 [[B:%.*]])
49; CHECK-NEXT:    ret i32 [[TMP1]]
50;
51  %not = xor i32 %A, -1
52  %l0 = icmp ugt i32 %not, %B
53  %l1 = select i1 %l0, i32 %B, i32 %not
54  %x = sub i32 %not, %l1
55  ret i32 %x
56}
57
58
59define i32 @max_na_bi_minux_na(i32 %A, i32 %Bi) {
60; CHECK-LABEL: @max_na_bi_minux_na(
61; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[BI:%.*]], i32 [[A:%.*]])
62; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 0, [[TMP1]]
63; CHECK-NEXT:    ret i32 [[TMP2]]
64;
65  %B =  xor i32 %Bi, -1
66  %not = xor i32 %A, -1
67  %l0 = icmp ult i32 %not, %B
68  %l1 = select i1 %l0, i32 %not, i32 %B
69  %x = sub i32 %l1, %not
70  ret i32 %x
71}
72
73define i32 @na_minus_max_na_bi(i32 %A, i32 %Bi) {
74; CHECK-LABEL: @na_minus_max_na_bi(
75; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[BI:%.*]], i32 [[A:%.*]])
76; CHECK-NEXT:    ret i32 [[TMP1]]
77;
78  %B =  xor i32 %Bi, -1
79  %not = xor i32 %A, -1
80  %l0 = icmp ult i32 %not, %B
81  %l1 = select i1 %l0, i32 %not, i32 %B
82  %x = sub i32 %not, %l1
83  ret i32 %x
84}
85
86define i32 @max_bi_na_minus_na(i32 %A, i32 %Bi) {
87; CHECK-LABEL: @max_bi_na_minus_na(
88; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[BI:%.*]], i32 [[A:%.*]])
89; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 0, [[TMP1]]
90; CHECK-NEXT:    ret i32 [[TMP2]]
91;
92  %B =  xor i32 %Bi, -1
93  %not = xor i32 %A, -1
94  %l0 = icmp ugt i32 %not, %B
95  %l1 = select i1 %l0, i32 %B, i32 %not
96  %x = sub i32 %l1, %not
97  ret i32 %x
98}
99
100define i32 @na_minus_max_bi_na(i32 %A, i32 %Bi) {
101; CHECK-LABEL: @na_minus_max_bi_na(
102; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[BI:%.*]], i32 [[A:%.*]])
103; CHECK-NEXT:    ret i32 [[TMP1]]
104;
105  %B =  xor i32 %Bi, -1
106  %not = xor i32 %A, -1
107  %l0 = icmp ugt i32 %not, %B
108  %l1 = select i1 %l0, i32 %B, i32 %not
109  %x = sub i32 %not, %l1
110  ret i32 %x
111}
112
113
114define i32 @max_na_bi_minux_na_use(i32 %A, i32 %Bi) {
115; CHECK-LABEL: @max_na_bi_minux_na_use(
116; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], -32
117; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 -32
118; CHECK-NEXT:    [[L1:%.*]] = xor i32 [[TMP2]], -1
119; CHECK-NEXT:    [[X:%.*]] = sub i32 [[A]], [[TMP2]]
120; CHECK-NEXT:    call void @use32(i32 [[L1]])
121; CHECK-NEXT:    ret i32 [[X]]
122;
123  %not = xor i32 %A, -1
124  %l0 = icmp ult i32 %not, 31
125  %l1 = select i1 %l0, i32 %not, i32 31
126  %x = sub i32 %l1, %not
127  call void @use32(i32 %l1)
128  ret i32 %x
129}
130
131define i32 @na_minus_max_na_bi_use(i32 %A, i32 %Bi) {
132; CHECK-LABEL: @na_minus_max_na_bi_use(
133; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], -32
134; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 -32
135; CHECK-NEXT:    [[L1:%.*]] = xor i32 [[TMP2]], -1
136; CHECK-NEXT:    [[X:%.*]] = sub i32 [[TMP2]], [[A]]
137; CHECK-NEXT:    call void @use32(i32 [[L1]])
138; CHECK-NEXT:    ret i32 [[X]]
139;
140  %not = xor i32 %A, -1
141  %l0 = icmp ult i32 %not, 31
142  %l1 = select i1 %l0, i32 %not, i32 31
143  %x = sub i32 %not, %l1
144  call void @use32(i32 %l1)
145  ret i32 %x
146}
147
148define i32 @max_bi_na_minus_na_use(i32 %A, i32 %Bi) {
149; CHECK-LABEL: @max_bi_na_minus_na_use(
150; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[BI:%.*]], [[A:%.*]]
151; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
152; CHECK-NEXT:    [[L1:%.*]] = xor i32 [[TMP2]], -1
153; CHECK-NEXT:    [[X:%.*]] = sub i32 [[A]], [[TMP2]]
154; CHECK-NEXT:    call void @use32(i32 [[L1]])
155; CHECK-NEXT:    ret i32 [[X]]
156;
157  %not = xor i32 %A, -1
158  %B = xor i32 %Bi, -1
159  %l0 = icmp ult i32 %B, %not
160  %l1 = select i1 %l0, i32 %B, i32 %not
161  %x = sub i32 %l1, %not
162  call void @use32(i32 %l1)
163  ret i32 %x
164}
165
166define i32 @na_minus_max_bi_na_use(i32 %A, i32 %Bi) {
167; CHECK-LABEL: @na_minus_max_bi_na_use(
168; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[BI:%.*]], [[A:%.*]]
169; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
170; CHECK-NEXT:    [[L1:%.*]] = xor i32 [[TMP2]], -1
171; CHECK-NEXT:    [[X:%.*]] = sub i32 [[TMP2]], [[A]]
172; CHECK-NEXT:    call void @use32(i32 [[L1]])
173; CHECK-NEXT:    ret i32 [[X]]
174;
175  %not = xor i32 %A, -1
176  %B = xor i32 %Bi, -1
177  %l0 = icmp ult i32 %B, %not
178  %l1 = select i1 %l0, i32 %B, i32 %not
179  %x = sub i32 %not, %l1
180  call void @use32(i32 %l1)
181  ret i32 %x
182}
183
184
185define i32 @max_na_bi_minux_na_use2(i32 %A, i32 %Bi) {
186; CHECK-LABEL: @max_na_bi_minux_na_use2(
187; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
188; CHECK-NEXT:    [[L0:%.*]] = icmp ult i32 [[NOT]], 31
189; CHECK-NEXT:    [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 31
190; CHECK-NEXT:    [[X:%.*]] = sub i32 [[L1]], [[NOT]]
191; CHECK-NEXT:    call void @use32(i32 [[L1]])
192; CHECK-NEXT:    call void @use32(i32 [[NOT]])
193; CHECK-NEXT:    ret i32 [[X]]
194;
195  %not = xor i32 %A, -1
196  %l0 = icmp ult i32 %not, 31
197  %l1 = select i1 %l0, i32 %not, i32 31
198  %x = sub i32 %l1, %not
199  call void @use32(i32 %l1)
200  call void @use32(i32 %not)
201  ret i32 %x
202}
203
204define i32 @na_minus_max_na_bi_use2(i32 %A, i32 %Bi) {
205; CHECK-LABEL: @na_minus_max_na_bi_use2(
206; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
207; CHECK-NEXT:    [[L0:%.*]] = icmp ult i32 [[NOT]], 31
208; CHECK-NEXT:    [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 31
209; CHECK-NEXT:    [[X:%.*]] = sub i32 [[NOT]], [[L1]]
210; CHECK-NEXT:    call void @use32(i32 [[L1]])
211; CHECK-NEXT:    call void @use32(i32 [[NOT]])
212; CHECK-NEXT:    ret i32 [[X]]
213;
214  %not = xor i32 %A, -1
215  %l0 = icmp ult i32 %not, 31
216  %l1 = select i1 %l0, i32 %not, i32 31
217  %x = sub i32 %not, %l1
218  call void @use32(i32 %l1)
219  call void @use32(i32 %not)
220  ret i32 %x
221}
222
223define i32 @max_bi_na_minus_na_use2(i32 %A, i32 %Bi) {
224; CHECK-LABEL: @max_bi_na_minus_na_use2(
225; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
226; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[BI:%.*]], [[A]]
227; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
228; CHECK-NEXT:    [[L1:%.*]] = xor i32 [[TMP2]], -1
229; CHECK-NEXT:    [[X:%.*]] = sub i32 [[A]], [[TMP2]]
230; CHECK-NEXT:    call void @use32(i32 [[L1]])
231; CHECK-NEXT:    call void @use32(i32 [[NOT]])
232; CHECK-NEXT:    ret i32 [[X]]
233;
234  %not = xor i32 %A, -1
235  %B = xor i32 %Bi, -1
236  %l0 = icmp ult i32 %B, %not
237  %l1 = select i1 %l0, i32 %B, i32 %not
238  %x = sub i32 %l1, %not
239  call void @use32(i32 %l1)
240  call void @use32(i32 %not)
241  ret i32 %x
242}
243
244define i32 @na_minus_max_bi_na_use2(i32 %A, i32 %Bi) {
245; CHECK-LABEL: @na_minus_max_bi_na_use2(
246; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
247; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[BI:%.*]], [[A]]
248; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
249; CHECK-NEXT:    [[L1:%.*]] = xor i32 [[TMP2]], -1
250; CHECK-NEXT:    [[X:%.*]] = sub i32 [[TMP2]], [[A]]
251; CHECK-NEXT:    call void @use32(i32 [[L1]])
252; CHECK-NEXT:    call void @use32(i32 [[NOT]])
253; CHECK-NEXT:    ret i32 [[X]]
254;
255  %not = xor i32 %A, -1
256  %B = xor i32 %Bi, -1
257  %l0 = icmp ult i32 %B, %not
258  %l1 = select i1 %l0, i32 %B, i32 %not
259  %x = sub i32 %not, %l1
260  call void @use32(i32 %l1)
261  call void @use32(i32 %not)
262  ret i32 %x
263}
264
265define i8 @umin_not_sub(i8 %x, i8 %y) {
266; CHECK-LABEL: @umin_not_sub(
267; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
268; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Y]]
269; CHECK-NEXT:    [[MINXY:%.*]] = xor i8 [[TMP2]], -1
270; CHECK-NEXT:    [[SUBX:%.*]] = sub i8 [[TMP2]], [[X]]
271; CHECK-NEXT:    [[SUBY:%.*]] = sub i8 [[TMP2]], [[Y]]
272; CHECK-NEXT:    call void @use8(i8 [[SUBX]])
273; CHECK-NEXT:    call void @use8(i8 [[SUBY]])
274; CHECK-NEXT:    ret i8 [[MINXY]]
275;
276  %nx = xor i8 %x, -1
277  %ny = xor i8 %y, -1
278  %cmpxy = icmp ult i8 %nx, %ny
279  %minxy = select i1 %cmpxy, i8 %nx, i8 %ny
280  %subx = sub i8 %nx, %minxy
281  %suby = sub i8 %ny, %minxy
282  call void @use8(i8 %subx)
283  call void @use8(i8 %suby)
284  ret i8 %minxy
285}
286
287define i8 @umin_not_sub_rev(i8 %x, i8 %y) {
288; CHECK-LABEL: @umin_not_sub_rev(
289; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
290; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Y]]
291; CHECK-NEXT:    [[MINXY:%.*]] = xor i8 [[TMP2]], -1
292; CHECK-NEXT:    [[SUBX:%.*]] = sub i8 [[X]], [[TMP2]]
293; CHECK-NEXT:    [[SUBY:%.*]] = sub i8 [[Y]], [[TMP2]]
294; CHECK-NEXT:    call void @use8(i8 [[SUBX]])
295; CHECK-NEXT:    call void @use8(i8 [[SUBY]])
296; CHECK-NEXT:    ret i8 [[MINXY]]
297;
298  %nx = xor i8 %x, -1
299  %ny = xor i8 %y, -1
300  %cmpxy = icmp ult i8 %nx, %ny
301  %minxy = select i1 %cmpxy, i8 %nx, i8 %ny
302  %subx = sub i8 %minxy, %nx
303  %suby = sub i8 %minxy, %ny
304  call void @use8(i8 %subx)
305  call void @use8(i8 %suby)
306  ret i8 %minxy
307}
308
309define void @umin3_not_all_ops_extra_uses_invert_subs(i8 %x, i8 %y, i8 %z) {
310; CHECK-LABEL: @umin3_not_all_ops_extra_uses_invert_subs(
311; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], [[Z:%.*]]
312; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Z]]
313; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i8 [[TMP2]], [[Y:%.*]]
314; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[Y]]
315; CHECK-NEXT:    [[TMP5:%.*]] = xor i8 [[TMP4]], -1
316; CHECK-NEXT:    [[XMIN:%.*]] = sub i8 [[TMP4]], [[X]]
317; CHECK-NEXT:    [[YMIN:%.*]] = sub i8 [[TMP4]], [[Y]]
318; CHECK-NEXT:    [[ZMIN:%.*]] = sub i8 [[TMP4]], [[Z]]
319; CHECK-NEXT:    call void @use8(i8 [[TMP5]])
320; CHECK-NEXT:    call void @use8(i8 [[XMIN]])
321; CHECK-NEXT:    call void @use8(i8 [[YMIN]])
322; CHECK-NEXT:    call void @use8(i8 [[ZMIN]])
323; CHECK-NEXT:    ret void
324;
325  %xn = xor i8 %x, -1
326  %yn = xor i8 %y, -1
327  %zn = xor i8 %z, -1
328  %cmpxz = icmp ult i8 %xn, %zn
329  %minxz = select i1 %cmpxz, i8 %xn, i8 %zn
330  %cmpxyz = icmp ult i8 %minxz, %yn
331  %minxyz = select i1 %cmpxyz, i8 %minxz, i8 %yn
332  %xmin = sub i8 %xn, %minxyz
333  %ymin = sub i8 %yn, %minxyz
334  %zmin = sub i8 %zn, %minxyz
335  call void @use8(i8 %minxyz)
336  call void @use8(i8 %xmin)
337  call void @use8(i8 %ymin)
338  call void @use8(i8 %zmin)
339  ret void
340}
341
342declare void @use8(i8)
343declare void @use32(i32 %u)
344