[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / result-of-add-of-negative-or-zero-is-non-zero-and-no-underflow.ll
blobe2f256140b5195bccba098f7a77ad5f666c06791
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 declare void @use8(i8)
6 declare void @use1(i1)
7 declare void @llvm.assume(i1)
9 define i1 @t0(i8 %base, i8 %offset) {
10 ; CHECK-LABEL: @t0(
11 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
12 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
13 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
14 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
15 ; CHECK-NEXT:    ret i1 [[TMP2]]
17   %adjusted = add i8 %base, %offset
18   call void @use8(i8 %adjusted)
19   %not_null = icmp ne i8 %adjusted, 0
20   %no_underflow = icmp ule i8 %adjusted, %base
21   %r = and i1 %not_null, %no_underflow
22   ret i1 %r
25 define i1 @t0_logical(i8 %base, i8 %offset) {
26 ; CHECK-LABEL: @t0_logical(
27 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
28 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
29 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
30 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
31 ; CHECK-NEXT:    ret i1 [[TMP2]]
33   %adjusted = add i8 %base, %offset
34   call void @use8(i8 %adjusted)
35   %not_null = icmp ne i8 %adjusted, 0
36   %no_underflow = icmp ule i8 %adjusted, %base
37   %r = select i1 %not_null, i1 %no_underflow, i1 false
38   ret i1 %r
41 ; We need to produce extra instruction, so one of icmp's must go away.
42 define i1 @t1_oneuse0(i8 %base, i8 %offset) {
43 ; CHECK-LABEL: @t1_oneuse0(
44 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
45 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
46 ; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
47 ; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
48 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
49 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
50 ; CHECK-NEXT:    ret i1 [[TMP2]]
52   %adjusted = add i8 %base, %offset
53   call void @use8(i8 %adjusted)
54   %not_null = icmp ne i8 %adjusted, 0
55   call void @use1(i1 %not_null)
56   %no_underflow = icmp ule i8 %adjusted, %base
57   %r = and i1 %not_null, %no_underflow
58   ret i1 %r
61 define i1 @t1_oneuse0_logical(i8 %base, i8 %offset) {
62 ; CHECK-LABEL: @t1_oneuse0_logical(
63 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
64 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
65 ; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
66 ; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
67 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
68 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
69 ; CHECK-NEXT:    ret i1 [[TMP2]]
71   %adjusted = add i8 %base, %offset
72   call void @use8(i8 %adjusted)
73   %not_null = icmp ne i8 %adjusted, 0
74   call void @use1(i1 %not_null)
75   %no_underflow = icmp ule i8 %adjusted, %base
76   %r = select i1 %not_null, i1 %no_underflow, i1 false
77   ret i1 %r
79 define i1 @t2_oneuse1(i8 %base, i8 %offset) {
80 ; CHECK-LABEL: @t2_oneuse1(
81 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
82 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
83 ; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ule i8 [[ADJUSTED]], [[BASE]]
84 ; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
85 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
86 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
87 ; CHECK-NEXT:    ret i1 [[TMP2]]
89   %adjusted = add i8 %base, %offset
90   call void @use8(i8 %adjusted)
91   %not_null = icmp ne i8 %adjusted, 0
92   %no_underflow = icmp ule i8 %adjusted, %base
93   call void @use1(i1 %no_underflow)
94   %r = and i1 %not_null, %no_underflow
95   ret i1 %r
98 define i1 @t2_oneuse1_logical(i8 %base, i8 %offset) {
99 ; CHECK-LABEL: @t2_oneuse1_logical(
100 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
101 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
102 ; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ule i8 [[ADJUSTED]], [[BASE]]
103 ; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
104 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
105 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
106 ; CHECK-NEXT:    ret i1 [[TMP2]]
108   %adjusted = add i8 %base, %offset
109   call void @use8(i8 %adjusted)
110   %not_null = icmp ne i8 %adjusted, 0
111   %no_underflow = icmp ule i8 %adjusted, %base
112   call void @use1(i1 %no_underflow)
113   %r = select i1 %not_null, i1 %no_underflow, i1 false
114   ret i1 %r
116 define i1 @n3_oneuse2_bad(i8 %base, i8 %offset) {
117 ; CHECK-LABEL: @n3_oneuse2_bad(
118 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
119 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
120 ; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
121 ; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
122 ; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ule i8 [[ADJUSTED]], [[BASE]]
123 ; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
124 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
125 ; CHECK-NEXT:    ret i1 [[R]]
127   %adjusted = add i8 %base, %offset
128   call void @use8(i8 %adjusted)
129   %not_null = icmp ne i8 %adjusted, 0
130   call void @use1(i1 %not_null)
131   %no_underflow = icmp ule i8 %adjusted, %base
132   call void @use1(i1 %no_underflow)
133   %r = and i1 %not_null, %no_underflow
134   ret i1 %r
137 define i1 @n3_oneuse2_bad_logical(i8 %base, i8 %offset) {
138 ; CHECK-LABEL: @n3_oneuse2_bad_logical(
139 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
140 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
141 ; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
142 ; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
143 ; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ule i8 [[ADJUSTED]], [[BASE]]
144 ; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
145 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
146 ; CHECK-NEXT:    ret i1 [[R]]
148   %adjusted = add i8 %base, %offset
149   call void @use8(i8 %adjusted)
150   %not_null = icmp ne i8 %adjusted, 0
151   call void @use1(i1 %not_null)
152   %no_underflow = icmp ule i8 %adjusted, %base
153   call void @use1(i1 %no_underflow)
154   %r = select i1 %not_null, i1 %no_underflow, i1 false
155   ret i1 %r
158 define i1 @t4_commutativity0(i8 %base, i8 %offset) {
159 ; CHECK-LABEL: @t4_commutativity0(
160 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
161 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
162 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
163 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
164 ; CHECK-NEXT:    ret i1 [[TMP2]]
166   %adjusted = add i8 %base, %offset
167   call void @use8(i8 %adjusted)
168   %not_null = icmp ne i8 %adjusted, 0
169   %no_underflow = icmp ule i8 %adjusted, %base
170   %r = and i1 %no_underflow, %not_null ; swapped
171   ret i1 %r
174 define i1 @t4_commutativity0_logical(i8 %base, i8 %offset) {
175 ; CHECK-LABEL: @t4_commutativity0_logical(
176 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
177 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
178 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
179 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
180 ; CHECK-NEXT:    ret i1 [[TMP2]]
182   %adjusted = add i8 %base, %offset
183   call void @use8(i8 %adjusted)
184   %not_null = icmp ne i8 %adjusted, 0
185   %no_underflow = icmp ule i8 %adjusted, %base
186   %r = select i1 %no_underflow, i1 %not_null, i1 false ; swapped
187   ret i1 %r
189 define i1 @t5_commutativity1(i8 %base, i8 %offset) {
190 ; CHECK-LABEL: @t5_commutativity1(
191 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
192 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
193 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
194 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
195 ; CHECK-NEXT:    ret i1 [[TMP2]]
197   %adjusted = add i8 %base, %offset
198   call void @use8(i8 %adjusted)
199   %not_null = icmp ne i8 %adjusted, 0
200   %no_underflow = icmp uge i8 %base, %adjusted ; swapped
201   %r = and i1 %not_null, %no_underflow
202   ret i1 %r
205 define i1 @t5_commutativity1_logical(i8 %base, i8 %offset) {
206 ; CHECK-LABEL: @t5_commutativity1_logical(
207 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
208 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
209 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
210 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
211 ; CHECK-NEXT:    ret i1 [[TMP2]]
213   %adjusted = add i8 %base, %offset
214   call void @use8(i8 %adjusted)
215   %not_null = icmp ne i8 %adjusted, 0
216   %no_underflow = icmp uge i8 %base, %adjusted ; swapped
217   %r = select i1 %not_null, i1 %no_underflow, i1 false
218   ret i1 %r
220 define i1 @t6_commutativity3(i8 %base, i8 %offset) {
221 ; CHECK-LABEL: @t6_commutativity3(
222 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
223 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
224 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
225 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
226 ; CHECK-NEXT:    ret i1 [[TMP2]]
228   %adjusted = add i8 %base, %offset
229   call void @use8(i8 %adjusted)
230   %not_null = icmp ne i8 %adjusted, 0
231   %no_underflow = icmp uge i8 %base, %adjusted ; swapped
232   %r = and i1 %no_underflow, %not_null ; swapped
233   ret i1 %r
236 define i1 @t6_commutativity3_logical(i8 %base, i8 %offset) {
237 ; CHECK-LABEL: @t6_commutativity3_logical(
238 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
239 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
240 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
241 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
242 ; CHECK-NEXT:    ret i1 [[TMP2]]
244   %adjusted = add i8 %base, %offset
245   call void @use8(i8 %adjusted)
246   %not_null = icmp ne i8 %adjusted, 0
247   %no_underflow = icmp uge i8 %base, %adjusted ; swapped
248   %r = select i1 %no_underflow, i1 %not_null, i1 false ; swapped
249   ret i1 %r
252 ; We could have the opposite question, did we get null or overflow happened?
253 define i1 @t7(i8 %base, i8 %offset) {
254 ; CHECK-LABEL: @t7(
255 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
256 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
257 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[ADJUSTED]], -1
258 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i8 [[TMP1]], [[BASE]]
259 ; CHECK-NEXT:    ret i1 [[TMP2]]
261   %adjusted = add i8 %base, %offset
262   call void @use8(i8 %adjusted)
263   %not_null = icmp eq i8 %adjusted, 0
264   %no_underflow = icmp ugt i8 %adjusted, %base
265   %r = or i1 %not_null, %no_underflow
266   ret i1 %r
269 define i1 @t7_logical(i8 %base, i8 %offset) {
270 ; CHECK-LABEL: @t7_logical(
271 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
272 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
273 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[ADJUSTED]], -1
274 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i8 [[TMP1]], [[BASE]]
275 ; CHECK-NEXT:    ret i1 [[TMP2]]
277   %adjusted = add i8 %base, %offset
278   call void @use8(i8 %adjusted)
279   %not_null = icmp eq i8 %adjusted, 0
280   %no_underflow = icmp ugt i8 %adjusted, %base
281   %r = select i1 %not_null, i1 true, i1 %no_underflow
282   ret i1 %r
285 ; The comparison can be with any of the values being added.
286 define i1 @t8(i8 %base, i8 %offset) {
287 ; CHECK-LABEL: @t8(
288 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
289 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
290 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[BASE]]
291 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[OFFSET]]
292 ; CHECK-NEXT:    ret i1 [[TMP2]]
294   %adjusted = add i8 %base, %offset
295   call void @use8(i8 %adjusted)
296   %not_null = icmp ne i8 %adjusted, 0
297   %no_underflow = icmp ule i8 %adjusted, %offset
298   %r = and i1 %not_null, %no_underflow
299   ret i1 %r
302 define i1 @t8_logical(i8 %base, i8 %offset) {
303 ; CHECK-LABEL: @t8_logical(
304 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
305 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
306 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[BASE]]
307 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[OFFSET]]
308 ; CHECK-NEXT:    ret i1 [[TMP2]]
310   %adjusted = add i8 %base, %offset
311   call void @use8(i8 %adjusted)
312   %not_null = icmp ne i8 %adjusted, 0
313   %no_underflow = icmp ule i8 %adjusted, %offset
314   %r = select i1 %not_null, i1 %no_underflow, i1 false
315   ret i1 %r