xref: /llvm-project/llvm/test/Transforms/InstCombine/select-binop-foldable-floating-point.ll (revision 96b14f2ccb749010daea7a67963abed83456318c)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define float @select_maybe_nan_fadd(i1 %cond, float %A, float %B) {
5; CHECK-LABEL: @select_maybe_nan_fadd(
6; CHECK-NEXT:    [[C:%.*]] = fadd float [[A:%.*]], [[B:%.*]]
7; CHECK-NEXT:    [[D:%.*]] = select i1 [[COND:%.*]], float [[C]], float [[A]]
8; CHECK-NEXT:    ret float [[D]]
9;
10  %C = fadd float %A, %B
11  %D = select i1 %cond, float %C, float %A
12  ret float %D
13}
14
15define float @select_fpclass_fadd(i1 %cond, float nofpclass(nan) %A, float %B) {
16; CHECK-LABEL: @select_fpclass_fadd(
17; CHECK-NEXT:    [[C:%.*]] = select i1 [[COND:%.*]], float [[B:%.*]], float -0.000000e+00
18; CHECK-NEXT:    [[D:%.*]] = fadd float [[A:%.*]], [[C]]
19; CHECK-NEXT:    ret float [[D]]
20;
21  %C = fadd float %A, %B
22  %D = select i1 %cond, float %C, float %A
23  ret float %D
24}
25
26define float @select_nnan_fadd(i1 %cond, float %A, float %B) {
27; CHECK-LABEL: @select_nnan_fadd(
28; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float -0.000000e+00
29; CHECK-NEXT:    [[D:%.*]] = fadd float [[A:%.*]], [[C]]
30; CHECK-NEXT:    ret float [[D]]
31;
32  %C = fadd float %A, %B
33  %D = select nnan i1 %cond, float %C, float %A
34  ret float %D
35}
36
37define float @select_nnan_fadd_swapped(i1 %cond, float %A, float %B) {
38; CHECK-LABEL: @select_nnan_fadd_swapped(
39; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float -0.000000e+00, float [[B:%.*]]
40; CHECK-NEXT:    [[D:%.*]] = fadd float [[A:%.*]], [[C]]
41; CHECK-NEXT:    ret float [[D]]
42;
43  %C = fadd float %A, %B
44  %D = select nnan i1 %cond, float %A, float %C
45  ret float %D
46}
47
48define float @select_nnan_fadd_fast_math(i1 %cond, float %A, float %B) {
49; CHECK-LABEL: @select_nnan_fadd_fast_math(
50; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float -0.000000e+00
51; CHECK-NEXT:    [[D:%.*]] = fadd reassoc nnan arcp contract afn float [[A:%.*]], [[C]]
52; CHECK-NEXT:    ret float [[D]]
53;
54  %C = fadd fast float %A, %B
55  %D = select nnan i1 %cond, float %C, float %A
56  ret float %D
57}
58
59define float @select_nnan_fadd_swapped_fast_math(i1 %cond, float %A, float %B) {
60; CHECK-LABEL: @select_nnan_fadd_swapped_fast_math(
61; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float -0.000000e+00, float [[B:%.*]]
62; CHECK-NEXT:    [[D:%.*]] = fadd reassoc nnan arcp contract afn float [[A:%.*]], [[C]]
63; CHECK-NEXT:    ret float [[D]]
64;
65  %C = fadd fast float %A, %B
66  %D = select nnan i1 %cond, float %A, float %C
67  ret float %D
68}
69
70define <4 x float> @select_nnan_nsz_fadd_v4f32(<4 x i1> %cond, <4 x float> %A, <4 x float> %B) {
71; CHECK-LABEL: @select_nnan_nsz_fadd_v4f32(
72; CHECK-NEXT:    [[C:%.*]] = select nnan nsz <4 x i1> [[COND:%.*]], <4 x float> [[B:%.*]], <4 x float> zeroinitializer
73; CHECK-NEXT:    [[D:%.*]] = fadd nnan nsz <4 x float> [[A:%.*]], [[C]]
74; CHECK-NEXT:    ret <4 x float> [[D]]
75;
76  %C = fadd nsz nnan <4 x float> %A, %B
77  %D = select nsz nnan <4 x i1> %cond, <4 x float> %C, <4 x float> %A
78  ret <4 x float> %D
79}
80
81define <vscale x 4 x float> @select_nnan_nsz_fadd_nxv4f32(<vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %B) {
82; CHECK-LABEL: @select_nnan_nsz_fadd_nxv4f32(
83; CHECK-NEXT:    [[C:%.*]] = select nnan nsz <vscale x 4 x i1> [[COND:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> zeroinitializer
84; CHECK-NEXT:    [[D:%.*]] = fadd nnan nsz <vscale x 4 x float> [[A:%.*]], [[C]]
85; CHECK-NEXT:    ret <vscale x 4 x float> [[D]]
86;
87  %C = fadd nnan nsz <vscale x 4 x float> %A, %B
88  %D = select nnan nsz <vscale x 4 x i1> %cond, <vscale x 4 x float> %C, <vscale x 4 x float> %A
89  ret <vscale x 4 x float> %D
90}
91
92define <vscale x 4 x float> @select_nnan_nsz_fadd_nxv4f32_swapops(<vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %B) {
93; CHECK-LABEL: @select_nnan_nsz_fadd_nxv4f32_swapops(
94; CHECK-NEXT:    [[C:%.*]] = select fast <vscale x 4 x i1> [[COND:%.*]], <vscale x 4 x float> zeroinitializer, <vscale x 4 x float> [[B:%.*]]
95; CHECK-NEXT:    [[D:%.*]] = fadd fast <vscale x 4 x float> [[A:%.*]], [[C]]
96; CHECK-NEXT:    ret <vscale x 4 x float> [[D]]
97;
98  %C = fadd fast <vscale x 4 x float> %A, %B
99  %D = select nnan fast <vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %C
100  ret <vscale x 4 x float> %D
101}
102
103define float @select_nnan_fmul(i1 %cond, float %A, float %B) {
104; CHECK-LABEL: @select_nnan_fmul(
105; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00
106; CHECK-NEXT:    [[D:%.*]] = fmul float [[A:%.*]], [[C]]
107; CHECK-NEXT:    ret float [[D]]
108;
109  %C = fmul float %A, %B
110  %D = select nnan i1 %cond, float %C, float %A
111  ret float %D
112}
113
114define float @select_nnan_fmul_swapped(i1 %cond, float %A, float %B) {
115; CHECK-LABEL: @select_nnan_fmul_swapped(
116; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]]
117; CHECK-NEXT:    [[D:%.*]] = fmul float [[A:%.*]], [[C]]
118; CHECK-NEXT:    ret float [[D]]
119;
120  %C = fmul float %A, %B
121  %D = select nnan i1 %cond, float %A, float %C
122  ret float %D
123}
124
125define float @select_nnan_fmul_fast_math(i1 %cond, float %A, float %B) {
126; CHECK-LABEL: @select_nnan_fmul_fast_math(
127; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00
128; CHECK-NEXT:    [[D:%.*]] = fmul reassoc nnan arcp contract afn float [[A:%.*]], [[C]]
129; CHECK-NEXT:    ret float [[D]]
130;
131  %C = fmul fast float %A, %B
132  %D = select nnan i1 %cond, float %C, float %A
133  ret float %D
134}
135
136define float @select_nnan_fmul_swapped_fast_math(i1 %cond, float %A, float %B) {
137; CHECK-LABEL: @select_nnan_fmul_swapped_fast_math(
138; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]]
139; CHECK-NEXT:    [[D:%.*]] = fmul reassoc nnan arcp contract afn float [[A:%.*]], [[C]]
140; CHECK-NEXT:    ret float [[D]]
141;
142  %C = fmul fast float %A, %B
143  %D = select nnan i1 %cond, float %A, float %C
144  ret float %D
145}
146
147define float @select_nnan_fsub(i1 %cond, float %A, float %B) {
148; CHECK-LABEL: @select_nnan_fsub(
149; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 0.000000e+00
150; CHECK-NEXT:    [[D:%.*]] = fsub float [[A:%.*]], [[C]]
151; CHECK-NEXT:    ret float [[D]]
152;
153  %C = fsub float %A, %B
154  %D = select nnan i1 %cond, float %C, float %A
155  ret float %D
156}
157
158define float @select_nnan_fsub_swapped(i1 %cond, float %A, float %B) {
159; CHECK-LABEL: @select_nnan_fsub_swapped(
160; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float 0.000000e+00, float [[B:%.*]]
161; CHECK-NEXT:    [[D:%.*]] = fsub float [[A:%.*]], [[C]]
162; CHECK-NEXT:    ret float [[D]]
163;
164  %C = fsub float %A, %B
165  %D = select nnan i1 %cond, float %A, float %C
166  ret float %D
167}
168
169define float @select_nnan_fsub_fast_math(i1 %cond, float %A, float %B) {
170; CHECK-LABEL: @select_nnan_fsub_fast_math(
171; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 0.000000e+00
172; CHECK-NEXT:    [[D:%.*]] = fsub reassoc nnan arcp contract afn float [[A:%.*]], [[C]]
173; CHECK-NEXT:    ret float [[D]]
174;
175  %C = fsub fast float %A, %B
176  %D = select nnan i1 %cond, float %C, float %A
177  ret float %D
178}
179
180define float @select_nnan_fsub_swapped_fast_math(i1 %cond, float %A, float %B) {
181; CHECK-LABEL: @select_nnan_fsub_swapped_fast_math(
182; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float 0.000000e+00, float [[B:%.*]]
183; CHECK-NEXT:    [[D:%.*]] = fsub reassoc nnan arcp contract afn float [[A:%.*]], [[C]]
184; CHECK-NEXT:    ret float [[D]]
185;
186  %C = fsub fast float %A, %B
187  %D = select nnan i1 %cond, float %A, float %C
188  ret float %D
189}
190
191define <4 x float> @select_nnan_nsz_fsub_v4f32(<4 x i1> %cond, <4 x float> %A, <4 x float> %B) {
192; CHECK-LABEL: @select_nnan_nsz_fsub_v4f32(
193; CHECK-NEXT:    [[C:%.*]] = select nnan nsz <4 x i1> [[COND:%.*]], <4 x float> [[B:%.*]], <4 x float> zeroinitializer
194; CHECK-NEXT:    [[D:%.*]] = fsub <4 x float> [[A:%.*]], [[C]]
195; CHECK-NEXT:    ret <4 x float> [[D]]
196;
197  %C = fsub <4 x float> %A, %B
198  %D = select nnan nsz <4 x i1> %cond, <4 x float> %C, <4 x float> %A
199  ret <4 x float> %D
200}
201
202define <vscale x 4 x float> @select_nnan_nsz_fsub_nxv4f32(<vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %B) {
203; CHECK-LABEL: @select_nnan_nsz_fsub_nxv4f32(
204; CHECK-NEXT:    [[C:%.*]] = select nnan nsz <vscale x 4 x i1> [[COND:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> zeroinitializer
205; CHECK-NEXT:    [[D:%.*]] = fsub <vscale x 4 x float> [[A:%.*]], [[C]]
206; CHECK-NEXT:    ret <vscale x 4 x float> [[D]]
207;
208  %C = fsub <vscale x 4 x float> %A, %B
209  %D = select nnan nsz <vscale x 4 x i1> %cond, <vscale x 4 x float> %C, <vscale x 4 x float> %A
210  ret <vscale x 4 x float> %D
211}
212
213; 'fsub' can only fold on the amount subtracted.
214define float @select_nnan_fsub_invalid(i1 %cond, float %A, float %B) {
215; CHECK-LABEL: @select_nnan_fsub_invalid(
216; CHECK-NEXT:    [[C:%.*]] = fsub float [[B:%.*]], [[A:%.*]]
217; CHECK-NEXT:    [[D:%.*]] = select nnan i1 [[COND:%.*]], float [[C]], float [[A]]
218; CHECK-NEXT:    ret float [[D]]
219;
220  %C = fsub float %B, %A
221  %D = select nnan i1 %cond, float %C, float %A
222  ret float %D
223}
224
225define float @select_nnan_fdiv(i1 %cond, float %A, float %B) {
226; CHECK-LABEL: @select_nnan_fdiv(
227; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00
228; CHECK-NEXT:    [[D:%.*]] = fdiv float [[A:%.*]], [[C]]
229; CHECK-NEXT:    ret float [[D]]
230;
231  %C = fdiv float %A, %B
232  %D = select nnan i1 %cond, float %C, float %A
233  ret float %D
234}
235
236define float @select_nnan_fdiv_swapped(i1 %cond, float %A, float %B) {
237; CHECK-LABEL: @select_nnan_fdiv_swapped(
238; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]]
239; CHECK-NEXT:    [[D:%.*]] = fdiv float [[A:%.*]], [[C]]
240; CHECK-NEXT:    ret float [[D]]
241;
242  %C = fdiv float %A, %B
243  %D = select nnan i1 %cond, float %A, float %C
244  ret float %D
245}
246
247define float @select_nnan_fdiv_fast_math(i1 %cond, float %A, float %B) {
248; CHECK-LABEL: @select_nnan_fdiv_fast_math(
249; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00
250; CHECK-NEXT:    [[D:%.*]] = fdiv reassoc nnan arcp contract afn float [[A:%.*]], [[C]]
251; CHECK-NEXT:    ret float [[D]]
252;
253  %C = fdiv fast float %A, %B
254  %D = select nnan i1 %cond, float %C, float %A
255  ret float %D
256}
257
258define float @select_nnan_fdiv_swapped_fast_math(i1 %cond, float %A, float %B) {
259; CHECK-LABEL: @select_nnan_fdiv_swapped_fast_math(
260; CHECK-NEXT:    [[C:%.*]] = select nnan i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]]
261; CHECK-NEXT:    [[D:%.*]] = fdiv reassoc nnan arcp contract afn float [[A:%.*]], [[C]]
262; CHECK-NEXT:    ret float [[D]]
263;
264  %C = fdiv fast float %A, %B
265  %D = select nnan i1 %cond, float %A, float %C
266  ret float %D
267}
268
269; 'fdiv' can only fold on the divisor amount.
270define float @select_nnan_fdiv_invalid(i1 %cond, float %A, float %B) {
271; CHECK-LABEL: @select_nnan_fdiv_invalid(
272; CHECK-NEXT:    [[C:%.*]] = fdiv float [[B:%.*]], [[A:%.*]]
273; CHECK-NEXT:    [[D:%.*]] = select nnan i1 [[COND:%.*]], float [[C]], float [[A]]
274; CHECK-NEXT:    ret float [[D]]
275;
276  %C = fdiv float %B, %A
277  %D = select nnan i1 %cond, float %C, float %A
278  ret float %D
279}
280