xref: /llvm-project/llvm/test/Transforms/InstCombine/fneg-fabs.ll (revision 862e35e25a68502433da0a8d0819448ff5745339)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4; (X <  +/-0.0) ? X : -X --> -fabs(X)
5; (X <= +/-0.0) ? X : -X --> -fabs(X)
6; One negative test with no fmf
7define double @select_noFMF_nfabs_lt(double %x) {
8; CHECK-LABEL: @select_noFMF_nfabs_lt(
9; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
10; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X]]
11; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], double [[X]], double [[NEGX]]
12; CHECK-NEXT:    ret double [[SEL]]
13;
14  %cmp = fcmp olt double %x, 0.000000e+00
15  %negX = fneg double %x
16  %sel = select i1 %cmp, double %x, double %negX
17  ret double %sel
18}
19
20; One test where the neg has fmfs.
21define double @select_nsz_nfabs_lt_fmfProp(double %x) {
22; CHECK-LABEL: @select_nsz_nfabs_lt_fmfProp(
23; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf nsz double @llvm.fabs.f64(double [[X:%.*]])
24; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan ninf nsz double [[TMP1]]
25; CHECK-NEXT:    ret double [[SEL]]
26;
27  %cmp = fcmp olt double %x, 0.000000e+00
28  %negX = fneg fast double %x
29  %sel = select nsz i1 %cmp, double %x, double %negX
30  ret double %sel
31}
32
33define double @select_nsz_nnan_nfabs_lt_fmfProp(double %x) {
34; CHECK-LABEL: @select_nsz_nnan_nfabs_lt_fmfProp(
35; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf nsz double @llvm.fabs.f64(double [[X:%.*]])
36; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan ninf nsz double [[TMP1]]
37; CHECK-NEXT:    ret double [[SEL]]
38;
39  %cmp = fcmp olt double %x, 0.000000e+00
40  %negX = fneg fast double %x
41  %sel = select nsz nnan i1 %cmp, double %x, double %negX
42  ret double %sel
43}
44
45; Tests with various predicate types.
46
47; This is not fabs because that could produce a different signbit for a NAN input.
48; PR59279
49
50define double @select_nsz_nfabs_ult(double %x) {
51; CHECK-LABEL: @select_nsz_nfabs_ult(
52; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult double [[X:%.*]], 0.000000e+00
53; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X]]
54; CHECK-NEXT:    [[SEL:%.*]] = select nsz i1 [[CMP]], double [[X]], double [[NEGX]]
55; CHECK-NEXT:    ret double [[SEL]]
56;
57  %cmp = fcmp ult double %x, 0.000000e+00
58  %negX = fneg double %x
59  %sel = select nsz i1 %cmp, double %x, double %negX
60  ret double %sel
61}
62
63define double @select_nsz_nnan_nfabs_ult(double %x) {
64; CHECK-LABEL: @select_nsz_nnan_nfabs_ult(
65; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
66; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
67; CHECK-NEXT:    ret double [[SEL]]
68;
69  %cmp = fcmp ult double %x, 0.000000e+00
70  %negX = fneg double %x
71  %sel = select nsz nnan i1 %cmp, double %x, double %negX
72  ret double %sel
73}
74
75; This is not fabs because that could produce a different signbit for a NAN input.
76; PR59279
77
78define double @select_nsz_nfabs_ole(double %x) {
79; CHECK-LABEL: @select_nsz_nfabs_ole(
80; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole double [[X:%.*]], 0.000000e+00
81; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X]]
82; CHECK-NEXT:    [[SEL:%.*]] = select nsz i1 [[CMP]], double [[X]], double [[NEGX]]
83; CHECK-NEXT:    ret double [[SEL]]
84;
85  %cmp = fcmp ole double %x, 0.000000e+00
86  %negX = fneg double %x
87  %sel = select nsz i1 %cmp, double %x, double %negX
88  ret double %sel
89}
90
91define double @select_nsz_nnan_nfabs_ole(double %x) {
92; CHECK-LABEL: @select_nsz_nnan_nfabs_ole(
93; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
94; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
95; CHECK-NEXT:    ret double [[SEL]]
96;
97  %cmp = fcmp ole double %x, 0.000000e+00
98  %negX = fneg double %x
99  %sel = select nsz nnan i1 %cmp, double %x, double %negX
100  ret double %sel
101}
102
103; This is not fabs because that could produce a different signbit for a NAN input.
104; PR59279
105
106define double @select_nsz_nfabs_ule(double %x) {
107; CHECK-LABEL: @select_nsz_nfabs_ule(
108; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule double [[X:%.*]], 0.000000e+00
109; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X]]
110; CHECK-NEXT:    [[SEL:%.*]] = select nsz i1 [[CMP]], double [[X]], double [[NEGX]]
111; CHECK-NEXT:    ret double [[SEL]]
112;
113  %cmp = fcmp ule double %x, 0.000000e+00
114  %negX = fneg double %x
115  %sel = select nsz i1 %cmp, double %x, double %negX
116  ret double %sel
117}
118
119define double @select_nsz_nnan_nfabs_ule(double %x) {
120; CHECK-LABEL: @select_nsz_nnan_nfabs_ule(
121; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
122; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
123; CHECK-NEXT:    ret double [[SEL]]
124;
125  %cmp = fcmp ule double %x, 0.000000e+00
126  %negX = fneg double %x
127  %sel = select nsz nnan i1 %cmp, double %x, double %negX
128  ret double %sel
129}
130
131; (X >  +/-0.0) ? -X : X --> -fabs(X)
132; (X >= +/-0.0) ? -X : X --> -fabs(X)
133; One negative test with no fmf
134define double @select_noFMF_nfabs_gt(double %x) {
135; CHECK-LABEL: @select_noFMF_nfabs_gt(
136; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[X:%.*]], 0.000000e+00
137; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X]]
138; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], double [[NEGX]], double [[X]]
139; CHECK-NEXT:    ret double [[SEL]]
140;
141  %cmp = fcmp ogt double %x, 0.000000e+00
142  %negX = fneg double %x
143  %sel = select i1 %cmp, double %negX, double %x
144  ret double %sel
145}
146
147; One test where the neg has fmfs.
148define double @select_nsz_nfabs_gt_fmfProp(double %x) {
149; CHECK-LABEL: @select_nsz_nfabs_gt_fmfProp(
150; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf nsz double @llvm.fabs.f64(double [[X:%.*]])
151; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan ninf nsz double [[TMP1]]
152; CHECK-NEXT:    ret double [[SEL]]
153;
154  %cmp = fcmp ogt double %x, 0.000000e+00
155  %negX = fneg fast double %x
156  %sel = select nsz i1 %cmp, double %negX, double %x
157  ret double %sel
158}
159
160define double @select_nsz_nnan_nfabs_gt_fmfProp(double %x) {
161; CHECK-LABEL: @select_nsz_nnan_nfabs_gt_fmfProp(
162; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf nsz double @llvm.fabs.f64(double [[X:%.*]])
163; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan ninf nsz double [[TMP1]]
164; CHECK-NEXT:    ret double [[SEL]]
165;
166  %cmp = fcmp ogt double %x, 0.000000e+00
167  %negX = fneg fast double %x
168  %sel = select nsz nnan i1 %cmp, double %negX, double %x
169  ret double %sel
170}
171
172; This is not fabs because that could produce a different signbit for a NAN input.
173; PR59279
174
175define double @select_nsz_nfabs_ogt(double %x) {
176; CHECK-LABEL: @select_nsz_nfabs_ogt(
177; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[X:%.*]], 0.000000e+00
178; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X]]
179; CHECK-NEXT:    [[SEL:%.*]] = select nsz i1 [[CMP]], double [[NEGX]], double [[X]]
180; CHECK-NEXT:    ret double [[SEL]]
181;
182  %cmp = fcmp ogt double %x, 0.000000e+00
183  %negX = fneg double %x
184  %sel = select nsz i1 %cmp, double %negX, double %x
185  ret double %sel
186}
187
188; Tests with various predicate types.
189
190define double @select_nsz_nnan_nfabs_ogt(double %x) {
191; CHECK-LABEL: @select_nsz_nnan_nfabs_ogt(
192; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
193; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
194; CHECK-NEXT:    ret double [[SEL]]
195;
196  %cmp = fcmp ogt double %x, 0.000000e+00
197  %negX = fneg double %x
198  %sel = select nsz nnan i1 %cmp, double %negX, double %x
199  ret double %sel
200}
201
202; This is not fabs because that could produce a different signbit for a NAN input.
203; PR59279
204
205define double @select_nsz_nfabs_ugt(double %x) {
206; CHECK-LABEL: @select_nsz_nfabs_ugt(
207; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt double [[X:%.*]], 0.000000e+00
208; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X]]
209; CHECK-NEXT:    [[SEL:%.*]] = select nsz i1 [[CMP]], double [[NEGX]], double [[X]]
210; CHECK-NEXT:    ret double [[SEL]]
211;
212  %cmp = fcmp ugt double %x, 0.000000e+00
213  %negX = fneg double %x
214  %sel = select nsz i1 %cmp, double %negX, double %x
215  ret double %sel
216}
217
218define double @select_nsz_nnan_nfabs_ugt(double %x) {
219; CHECK-LABEL: @select_nsz_nnan_nfabs_ugt(
220; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
221; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
222; CHECK-NEXT:    ret double [[SEL]]
223;
224  %cmp = fcmp ugt double %x, 0.000000e+00
225  %negX = fneg double %x
226  %sel = select nsz nnan i1 %cmp, double %negX, double %x
227  ret double %sel
228}
229
230; This is not fabs because that could produce a different signbit for a NAN input.
231; PR59279
232
233define double @select_nsz_nfabs_oge(double %x) {
234; CHECK-LABEL: @select_nsz_nfabs_oge(
235; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge double [[X:%.*]], 0.000000e+00
236; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X]]
237; CHECK-NEXT:    [[SEL:%.*]] = select nsz i1 [[CMP]], double [[NEGX]], double [[X]]
238; CHECK-NEXT:    ret double [[SEL]]
239;
240  %cmp = fcmp oge double %x, 0.000000e+00
241  %negX = fneg double %x
242  %sel = select nsz i1 %cmp, double %negX, double %x
243  ret double %sel
244}
245
246define double @select_nsz_nnan_nfabs_oge(double %x) {
247; CHECK-LABEL: @select_nsz_nnan_nfabs_oge(
248; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
249; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
250; CHECK-NEXT:    ret double [[SEL]]
251;
252  %cmp = fcmp oge double %x, 0.000000e+00
253  %negX = fneg double %x
254  %sel = select nsz nnan i1 %cmp, double %negX, double %x
255  ret double %sel
256}
257
258; This is not fabs because that could produce a different signbit for a NAN input.
259; PR59279
260
261define double @select_nsz_nfabs_uge(double %x) {
262; CHECK-LABEL: @select_nsz_nfabs_uge(
263; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge double [[X:%.*]], 0.000000e+00
264; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X]]
265; CHECK-NEXT:    [[SEL:%.*]] = select nsz i1 [[CMP]], double [[NEGX]], double [[X]]
266; CHECK-NEXT:    ret double [[SEL]]
267;
268  %cmp = fcmp uge double %x, 0.000000e+00
269  %negX = fneg double %x
270  %sel = select nsz i1 %cmp, double %negX, double %x
271  ret double %sel
272}
273
274define double @select_nsz_nnan_nfabs_uge(double %x) {
275; CHECK-LABEL: @select_nsz_nnan_nfabs_uge(
276; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
277; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
278; CHECK-NEXT:    ret double [[SEL]]
279;
280  %cmp = fcmp uge double %x, 0.000000e+00
281  %negX = fneg double %x
282  %sel = select nsz nnan i1 %cmp, double %negX, double %x
283  ret double %sel
284}
285
286; (X < +/-0.0) ? X : (0.0 - X) --> (0.0 - fabs(X))
287; One negative test with <=.
288define double @select_noFMF_fsubfabs_le(double %x) {
289; CHECK-LABEL: @select_noFMF_fsubfabs_le(
290; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole double [[X:%.*]], 0.000000e+00
291; CHECK-NEXT:    [[SUB:%.*]] = fsub double 0.000000e+00, [[X]]
292; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[CMP]], double [[X]], double [[SUB]]
293; CHECK-NEXT:    ret double [[RETVAL_0]]
294;
295  %cmp = fcmp ole double %x, 0.000000e+00
296  %sub = fsub double 0.000000e+00, %x
297  %retval.0 = select i1 %cmp, double %x, double %sub
298  ret double %retval.0
299}
300
301define double @select_noFMF_fsubfabs_olt(double %x) {
302; CHECK-LABEL: @select_noFMF_fsubfabs_olt(
303; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
304; CHECK-NEXT:    [[SUB:%.*]] = fsub double 0.000000e+00, [[X]]
305; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[CMP]], double [[X]], double [[SUB]]
306; CHECK-NEXT:    ret double [[RETVAL_0]]
307;
308  %cmp = fcmp olt double %x, 0.000000e+00
309  %sub = fsub double 0.000000e+00, %x
310  %retval.0 = select i1 %cmp, double %x, double %sub
311  ret double %retval.0
312}
313
314define double @select_noFMF_fsubfabs_ult(double %x) {
315; CHECK-LABEL: @select_noFMF_fsubfabs_ult(
316; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult double [[X:%.*]], 0.000000e+00
317; CHECK-NEXT:    [[SUB:%.*]] = fsub double 0.000000e+00, [[X]]
318; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[CMP]], double [[X]], double [[SUB]]
319; CHECK-NEXT:    ret double [[RETVAL_0]]
320;
321  %cmp = fcmp ult double %x, 0.000000e+00
322  %sub = fsub double 0.000000e+00, %x
323  %retval.0 = select i1 %cmp, double %x, double %sub
324  ret double %retval.0
325}
326
327
328; With nsz:
329; (X < +/-0.0) ? X : -X --> -fabs(X)
330define double @select_nsz_fnegfabs_olt(double %x) {
331; CHECK-LABEL: @select_nsz_fnegfabs_olt(
332; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
333; CHECK-NEXT:    [[NEGX:%.*]] = fneg nsz double [[X]]
334; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[CMP]], double [[X]], double [[NEGX]]
335; CHECK-NEXT:    ret double [[RETVAL_0]]
336;
337  %cmp = fcmp olt double %x, 0.000000e+00
338  %negX = fneg nsz double %x
339  %retval.0 = select i1 %cmp, double %x, double %negX
340  ret double %retval.0
341}
342
343define double @select_nsz_fnegfabs_ult(double %x) {
344; CHECK-LABEL: @select_nsz_fnegfabs_ult(
345; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult double [[X:%.*]], 0.000000e+00
346; CHECK-NEXT:    [[NEGX:%.*]] = fneg nsz double [[X]]
347; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[CMP]], double [[X]], double [[NEGX]]
348; CHECK-NEXT:    ret double [[RETVAL_0]]
349;
350  %cmp = fcmp ult double %x, 0.000000e+00
351  %negX = fneg nsz double %x
352  %retval.0 = select i1 %cmp, double %x, double %negX
353  ret double %retval.0
354}
355