OSDN Git Service

[ValueTracking] allow undef elements when matching vector abs
[android-x86/external-llvm.git] / test / Transforms / InstCombine / abs-1.ll
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
3
4 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
5
6 declare i32 @abs(i32)
7 declare i64 @labs(i64)
8 declare i64 @llabs(i64)
9
10 ; Test that the abs library call simplifier works correctly.
11 ; abs(x) -> x <s 0 ? -x : x.
12
13 define i32 @test_abs(i32 %x) {
14 ; CHECK-LABEL: @test_abs(
15 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
16 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[X]]
17 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[NEG]], i32 [[X]]
18 ; CHECK-NEXT:    ret i32 [[TMP2]]
19 ;
20   %ret = call i32 @abs(i32 %x)
21   ret i32 %ret
22 }
23
24 define i64 @test_labs(i64 %x) {
25 ; CHECK-LABEL: @test_labs(
26 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[X:%.*]], 0
27 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i64 0, [[X]]
28 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i64 [[NEG]], i64 [[X]]
29 ; CHECK-NEXT:    ret i64 [[TMP2]]
30 ;
31   %ret = call i64 @labs(i64 %x)
32   ret i64 %ret
33 }
34
35 define i64 @test_llabs(i64 %x) {
36 ; CHECK-LABEL: @test_llabs(
37 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[X:%.*]], 0
38 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i64 0, [[X]]
39 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i64 [[NEG]], i64 [[X]]
40 ; CHECK-NEXT:    ret i64 [[TMP2]]
41 ;
42   %ret = call i64 @llabs(i64 %x)
43   ret i64 %ret
44 }
45
46 ; We have a canonical form of abs to make CSE easier.
47
48 define i8 @abs_canonical_1(i8 %x) {
49 ; CHECK-LABEL: @abs_canonical_1(
50 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
51 ; CHECK-NEXT:    [[NEG:%.*]] = sub i8 0, [[X]]
52 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEG]], i8 [[X]]
53 ; CHECK-NEXT:    ret i8 [[ABS]]
54 ;
55   %cmp = icmp sgt i8 %x, 0
56   %neg = sub i8 0, %x
57   %abs = select i1 %cmp, i8 %x, i8 %neg
58   ret i8 %abs
59 }
60
61 ; Vectors should work too.
62
63 define <2 x i8> @abs_canonical_2(<2 x i8> %x) {
64 ; CHECK-LABEL: @abs_canonical_2(
65 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
66 ; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
67 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[NEG]], <2 x i8> [[X]]
68 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
69 ;
70   %cmp = icmp sgt <2 x i8> %x, <i8 -1, i8 -1>
71   %neg = sub <2 x i8> zeroinitializer, %x
72   %abs = select <2 x i1> %cmp, <2 x i8> %x, <2 x i8> %neg
73   ret <2 x i8> %abs
74 }
75
76 ; Even if a constant has undef elements.
77
78 define <2 x i8> @abs_canonical_2_vec_undef_elts(<2 x i8> %x) {
79 ; CHECK-LABEL: @abs_canonical_2_vec_undef_elts(
80 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
81 ; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
82 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[NEG]], <2 x i8> [[X]]
83 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
84 ;
85   %cmp = icmp sgt <2 x i8> %x, <i8 undef, i8 -1>
86   %neg = sub <2 x i8> zeroinitializer, %x
87   %abs = select <2 x i1> %cmp, <2 x i8> %x, <2 x i8> %neg
88   ret <2 x i8> %abs
89 }
90
91 ; NSW should not change.
92
93 define i8 @abs_canonical_3(i8 %x) {
94 ; CHECK-LABEL: @abs_canonical_3(
95 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
96 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i8 0, [[X]]
97 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEG]], i8 [[X]]
98 ; CHECK-NEXT:    ret i8 [[ABS]]
99 ;
100   %cmp = icmp slt i8 %x, 0
101   %neg = sub nsw i8 0, %x
102   %abs = select i1 %cmp, i8 %neg, i8 %x
103   ret i8 %abs
104 }
105
106 define i8 @abs_canonical_4(i8 %x) {
107 ; CHECK-LABEL: @abs_canonical_4(
108 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
109 ; CHECK-NEXT:    [[NEG:%.*]] = sub i8 0, [[X]]
110 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEG]], i8 [[X]]
111 ; CHECK-NEXT:    ret i8 [[ABS]]
112 ;
113   %cmp = icmp slt i8 %x, 1
114   %neg = sub i8 0, %x
115   %abs = select i1 %cmp, i8 %neg, i8 %x
116   ret i8 %abs
117 }
118
119 define i32 @abs_canonical_5(i8 %x) {
120 ; CHECK-LABEL: @abs_canonical_5(
121 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
122 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[X]] to i32
123 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[CONV]]
124 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[CONV]]
125 ; CHECK-NEXT:    ret i32 [[ABS]]
126 ;
127   %cmp = icmp sgt i8 %x, 0
128   %conv = sext i8 %x to i32
129   %neg = sub i32 0, %conv
130   %abs = select i1 %cmp, i32 %conv, i32 %neg
131   ret i32 %abs
132 }
133
134 ; We have a canonical form of nabs to make CSE easier.
135
136 define i8 @nabs_canonical_1(i8 %x) {
137 ; CHECK-LABEL: @nabs_canonical_1(
138 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
139 ; CHECK-NEXT:    [[NEG:%.*]] = sub i8 0, [[X]]
140 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[NEG]]
141 ; CHECK-NEXT:    ret i8 [[ABS]]
142 ;
143   %cmp = icmp sgt i8 %x, 0
144   %neg = sub i8 0, %x
145   %abs = select i1 %cmp, i8 %neg, i8 %x
146   ret i8 %abs
147 }
148
149 ; Vectors should work too.
150
151 define <2 x i8> @nabs_canonical_2(<2 x i8> %x) {
152 ; CHECK-LABEL: @nabs_canonical_2(
153 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
154 ; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
155 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[X]], <2 x i8> [[NEG]]
156 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
157 ;
158   %cmp = icmp sgt <2 x i8> %x, <i8 -1, i8 -1>
159   %neg = sub <2 x i8> zeroinitializer, %x
160   %abs = select <2 x i1> %cmp, <2 x i8> %neg, <2 x i8> %x
161   ret <2 x i8> %abs
162 }
163
164 ; Even if a constant has undef elements.
165
166 define <2 x i8> @nabs_canonical_2_vec_undef_elts(<2 x i8> %x) {
167 ; CHECK-LABEL: @nabs_canonical_2_vec_undef_elts(
168 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
169 ; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
170 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[X]], <2 x i8> [[NEG]]
171 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
172 ;
173   %cmp = icmp sgt <2 x i8> %x, <i8 -1, i8 undef>
174   %neg = sub <2 x i8> zeroinitializer, %x
175   %abs = select <2 x i1> %cmp, <2 x i8> %neg, <2 x i8> %x
176   ret <2 x i8> %abs
177 }
178
179 ; NSW should not change.
180
181 define i8 @nabs_canonical_3(i8 %x) {
182 ; CHECK-LABEL: @nabs_canonical_3(
183 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
184 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i8 0, [[X]]
185 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[NEG]]
186 ; CHECK-NEXT:    ret i8 [[ABS]]
187 ;
188   %cmp = icmp slt i8 %x, 0
189   %neg = sub nsw i8 0, %x
190   %abs = select i1 %cmp, i8 %x, i8 %neg
191   ret i8 %abs
192 }
193
194 define i8 @nabs_canonical_4(i8 %x) {
195 ; CHECK-LABEL: @nabs_canonical_4(
196 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
197 ; CHECK-NEXT:    [[NEG:%.*]] = sub i8 0, [[X]]
198 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[NEG]]
199 ; CHECK-NEXT:    ret i8 [[ABS]]
200 ;
201   %cmp = icmp slt i8 %x, 1
202   %neg = sub i8 0, %x
203   %abs = select i1 %cmp, i8 %x, i8 %neg
204   ret i8 %abs
205 }
206
207 define i32 @nabs_canonical_5(i8 %x) {
208 ; CHECK-LABEL: @nabs_canonical_5(
209 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
210 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[X]] to i32
211 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[CONV]]
212 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[CONV]], i32 [[NEG]]
213 ; CHECK-NEXT:    ret i32 [[ABS]]
214 ;
215   %cmp = icmp sgt i8 %x, 0
216   %conv = sext i8 %x to i32
217   %neg = sub i32 0, %conv
218   %abs = select i1 %cmp, i32 %neg, i32 %conv
219   ret i32 %abs
220 }
221
222 ; The following 5 tests use a shift+add+xor to implement abs():
223 ; B = ashr i8 A, 7  -- smear the sign bit.
224 ; xor (add A, B), B -- add -1 and flip bits if negative
225
226 define i8 @shifty_abs_commute0(i8 %x) {
227 ; CHECK-LABEL: @shifty_abs_commute0(
228 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 0
229 ; CHECK-NEXT:    [[TMP2:%.*]] = sub i8 0, [[X]]
230 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[X]]
231 ; CHECK-NEXT:    ret i8 [[ABS]]
232 ;
233   %signbit = ashr i8 %x, 7
234   %add = add i8 %signbit, %x
235   %abs = xor i8 %add, %signbit
236   ret i8 %abs
237 }
238
239 define i8 @shifty_abs_commute0_nsw(i8 %x) {
240 ; CHECK-LABEL: @shifty_abs_commute0_nsw(
241 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 0
242 ; CHECK-NEXT:    [[TMP2:%.*]] = sub nsw i8 0, [[X]]
243 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[X]]
244 ; CHECK-NEXT:    ret i8 [[ABS]]
245 ;
246   %signbit = ashr i8 %x, 7
247   %add = add nsw i8 %signbit, %x
248   %abs = xor i8 %add, %signbit
249   ret i8 %abs
250 }
251
252 ; The nuw flag creates a contradiction. If the shift produces all 1s, the only
253 ; way for the add to not wrap is for %x to be 0, but then the shift couldn't
254 ; have produced all 1s. We partially optimize this.
255 define i8 @shifty_abs_commute0_nuw(i8 %x) {
256 ; CHECK-LABEL: @shifty_abs_commute0_nuw(
257 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8 [[X:%.*]], 0
258 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 0
259 ; CHECK-NEXT:    ret i8 [[ABS]]
260 ;
261   %signbit = ashr i8 %x, 7
262   %add = add nuw i8 %signbit, %x
263   %abs = xor i8 %add, %signbit
264   ret i8 %abs
265 }
266
267 define <2 x i8> @shifty_abs_commute1(<2 x i8> %x) {
268 ; CHECK-LABEL: @shifty_abs_commute1(
269 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
270 ; CHECK-NEXT:    [[TMP2:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
271 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[TMP1]], <2 x i8> [[TMP2]], <2 x i8> [[X]]
272 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
273 ;
274   %signbit = ashr <2 x i8> %x, <i8 7, i8 7>
275   %add = add <2 x i8> %signbit, %x
276   %abs = xor <2 x i8> %signbit, %add
277   ret <2 x i8> %abs
278 }
279
280 define <2 x i8> @shifty_abs_commute2(<2 x i8> %x) {
281 ; CHECK-LABEL: @shifty_abs_commute2(
282 ; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i8> [[X:%.*]], <i8 3, i8 3>
283 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i8> [[Y]], zeroinitializer
284 ; CHECK-NEXT:    [[TMP2:%.*]] = sub <2 x i8> zeroinitializer, [[Y]]
285 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[TMP1]], <2 x i8> [[TMP2]], <2 x i8> [[Y]]
286 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
287 ;
288   %y = mul <2 x i8> %x, <i8 3, i8 3>   ; extra op to thwart complexity-based canonicalization
289   %signbit = ashr <2 x i8> %y, <i8 7, i8 7>
290   %add = add <2 x i8> %y, %signbit
291   %abs = xor <2 x i8> %signbit, %add
292   ret <2 x i8> %abs
293 }
294
295 define i8 @shifty_abs_commute3(i8 %x) {
296 ; CHECK-LABEL: @shifty_abs_commute3(
297 ; CHECK-NEXT:    [[Y:%.*]] = mul i8 [[X:%.*]], 3
298 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y]], 0
299 ; CHECK-NEXT:    [[TMP2:%.*]] = sub i8 0, [[Y]]
300 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[Y]]
301 ; CHECK-NEXT:    ret i8 [[ABS]]
302 ;
303   %y = mul i8 %x, 3                    ; extra op to thwart complexity-based canonicalization
304   %signbit = ashr i8 %y, 7
305   %add = add i8 %y, %signbit
306   %abs = xor i8 %add, %signbit
307   ret i8 %abs
308 }
309
310 ; Negative test - don't transform if it would increase instruction count.
311
312 declare void @extra_use(i8)
313
314 define i8 @shifty_abs_too_many_uses(i8 %x) {
315 ; CHECK-LABEL: @shifty_abs_too_many_uses(
316 ; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 7
317 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SIGNBIT]], [[X]]
318 ; CHECK-NEXT:    [[ABS:%.*]] = xor i8 [[ADD]], [[SIGNBIT]]
319 ; CHECK-NEXT:    call void @extra_use(i8 [[SIGNBIT]])
320 ; CHECK-NEXT:    ret i8 [[ABS]]
321 ;
322   %signbit = ashr i8 %x, 7
323   %add = add i8 %x, %signbit
324   %abs = xor i8 %add, %signbit
325   call void @extra_use(i8 %signbit)
326   ret i8 %abs
327 }
328
329 ; There's another way to make abs() using shift, xor, and subtract.
330 ; PR36036 - https://bugs.llvm.org/show_bug.cgi?id=36036
331
332 define i8 @shifty_sub(i8 %x) {
333 ; CHECK-LABEL: @shifty_sub(
334 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 0
335 ; CHECK-NEXT:    [[TMP2:%.*]] = sub i8 0, [[X]]
336 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[X]]
337 ; CHECK-NEXT:    ret i8 [[R]]
338 ;
339   %sh = ashr i8 %x, 7
340   %xor = xor i8 %x, %sh
341   %r = sub i8 %xor, %sh
342   ret i8 %r
343 }
344
345 define i8 @shifty_sub_nsw_commute(i8 %x) {
346 ; CHECK-LABEL: @shifty_sub_nsw_commute(
347 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 0
348 ; CHECK-NEXT:    [[TMP2:%.*]] = sub nsw i8 0, [[X]]
349 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[X]]
350 ; CHECK-NEXT:    ret i8 [[R]]
351 ;
352   %sh = ashr i8 %x, 7
353   %xor = xor i8 %sh, %x
354   %r = sub nsw i8 %xor, %sh
355   ret i8 %r
356 }
357
358 define <4 x i32> @shifty_sub_nuw_vec_commute(<4 x i32> %x) {
359 ; CHECK-LABEL: @shifty_sub_nuw_vec_commute(
360 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], zeroinitializer
361 ; CHECK-NEXT:    [[R:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[X]], <4 x i32> zeroinitializer
362 ; CHECK-NEXT:    ret <4 x i32> [[R]]
363 ;
364   %sh = ashr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31>
365   %xor = xor <4 x i32> %sh, %x
366   %r = sub nuw <4 x i32> %xor, %sh
367   ret <4 x i32> %r
368 }
369
370 define i12 @shifty_sub_nsw_nuw(i12 %x) {
371 ; CHECK-LABEL: @shifty_sub_nsw_nuw(
372 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i12 [[X:%.*]], 0
373 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i12 [[X]], i12 0
374 ; CHECK-NEXT:    ret i12 [[R]]
375 ;
376   %sh = ashr i12 %x, 11
377   %xor = xor i12 %x, %sh
378   %r = sub nsw nuw i12 %xor, %sh
379   ret i12 %r
380 }
381
382 define i8 @negate_abs(i8 %x) {
383 ; CHECK-LABEL: @negate_abs(
384 ; CHECK-NEXT:    [[N:%.*]] = sub i8 0, [[X:%.*]]
385 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[X]], 0
386 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i8 [[X]], i8 [[N]]
387 ; CHECK-NEXT:    ret i8 [[S]]
388 ;
389   %n = sub i8 0, %x
390   %c = icmp slt i8 %x, 0
391   %s = select i1 %c, i8 %n, i8 %x
392   %r = sub i8 0, %s
393   ret i8 %r
394 }
395
396 define <2 x i8> @negate_nabs(<2 x i8> %x) {
397 ; CHECK-LABEL: @negate_nabs(
398 ; CHECK-NEXT:    [[N:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]]
399 ; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i8> [[X]], zeroinitializer
400 ; CHECK-NEXT:    [[S:%.*]] = select <2 x i1> [[C]], <2 x i8> [[N]], <2 x i8> [[X]]
401 ; CHECK-NEXT:    ret <2 x i8> [[S]]
402 ;
403   %n = sub <2 x i8> zeroinitializer, %x
404   %c = icmp slt <2 x i8> %x, zeroinitializer
405   %s = select <2 x i1> %c, <2 x i8> %x, <2 x i8> %n
406   %r = sub <2 x i8> zeroinitializer, %s
407   ret <2 x i8> %r
408 }
409
410 define i1 @abs_must_be_positive(i32 %x) {
411 ; CHECK-LABEL: @abs_must_be_positive(
412 ; CHECK-NEXT:    ret i1 true
413 ;
414   %negx = sub nsw i32 0, %x
415   %c = icmp sge i32 %x, 0
416   %sel = select i1 %c, i32 %x, i32 %negx
417   %c2 = icmp sge i32 %sel, 0
418   ret i1 %c2
419 }
420