1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instsimplify -S | FileCheck %s
3
4; X == 42.0 ? X : 42.0 --> 42.0
5
6define double @oeq(double %x) {
7; CHECK-LABEL: @oeq(
8; CHECK-NEXT:    ret double 4.200000e+01
9;
10  %cmp = fcmp oeq double %x, 42.0
11  %cond = select i1 %cmp, double %x, double 42.0
12  ret double %cond
13}
14
15; X == 42.0 ? 42.0 : X --> X
16
17define float @oeq_swapped(float %x) {
18; CHECK-LABEL: @oeq_swapped(
19; CHECK-NEXT:    ret float [[X:%.*]]
20;
21  %cmp = fcmp oeq float %x, 42.0
22  %cond = select i1 %cmp, float 42.0, float %x
23  ret float %cond
24}
25
26; x != y ? x : y -> x if it's the right kind of != and at least
27; one of x and y is not negative zero.
28
29; X != 42.0 ? X : 42.0 --> X
30
31define double @une(double %x) {
32; CHECK-LABEL: @une(
33; CHECK-NEXT:    ret double [[X:%.*]]
34;
35  %cmp = fcmp une double %x, 42.0
36  %cond = select i1 %cmp, double %x, double 42.0
37  ret double %cond
38}
39
40; X != 42.0 ? 42.0 : X --> 42.0
41
42define double @une_swapped(double %x) {
43; CHECK-LABEL: @une_swapped(
44; CHECK-NEXT:    ret double 4.200000e+01
45;
46  %cmp = fcmp une double %x, 42.0
47  %cond = select i1 %cmp, double 42.0, double %x
48  ret double %cond
49}
50
51; X == 0.0 ? X : 0.0 --> ? (X could be -0.0)
52
53define double @oeq_zero(double %x) {
54; CHECK-LABEL: @oeq_zero(
55; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[X:%.*]], 0.000000e+00
56; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], double [[X]], double 0.000000e+00
57; CHECK-NEXT:    ret double [[COND]]
58;
59  %cmp = fcmp oeq double %x, 0.0
60  %cond = select i1 %cmp, double %x, double 0.0
61  ret double %cond
62}
63
64; X == 0.0 ? 0.0 : X --> ? (change sign if X is -0.0)
65
66define float @oeq_zero_swapped(float %x) {
67; CHECK-LABEL: @oeq_zero_swapped(
68; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
69; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], float 0.000000e+00, float [[X]]
70; CHECK-NEXT:    ret float [[COND]]
71;
72  %cmp = fcmp oeq float %x, 0.0
73  %cond = select i1 %cmp, float 0.0, float %x
74  ret float %cond
75}
76
77; X != 0.0 ? X : -0.0 --> ? (change sign if X is 0.0)
78
79define double @une_zero(double %x) {
80; CHECK-LABEL: @une_zero(
81; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[X:%.*]], 0.000000e+00
82; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], double [[X]], double -0.000000e+00
83; CHECK-NEXT:    ret double [[COND]]
84;
85  %cmp = fcmp une double %x, 0.0
86  %cond = select i1 %cmp, double %x, double -0.0
87  ret double %cond
88}
89
90; X != 0.0 ? -0.0 : X --> ? (X could be 0.0)
91
92define double @une_zero_swapped(double %x) {
93; CHECK-LABEL: @une_zero_swapped(
94; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[X:%.*]], 0.000000e+00
95; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], double -0.000000e+00, double [[X]]
96; CHECK-NEXT:    ret double [[COND]]
97;
98  %cmp = fcmp une double %x, 0.0
99  %cond = select i1 %cmp, double -0.0, double %x
100  ret double %cond
101}
102
103; X == 0.0 ? X : 0.0 --> 0.0
104
105define double @oeq_zero_nsz(double %x) {
106; CHECK-LABEL: @oeq_zero_nsz(
107; CHECK-NEXT:    ret double 0.000000e+00
108;
109  %cmp = fcmp oeq double %x, 0.0
110  %cond = select nsz i1 %cmp, double %x, double 0.0
111  ret double %cond
112}
113
114; X == 0.0 ? 0.0 : X --> X
115
116define float @oeq_zero_swapped_nsz(float %x) {
117; CHECK-LABEL: @oeq_zero_swapped_nsz(
118; CHECK-NEXT:    ret float [[X:%.*]]
119;
120  %cmp = fcmp oeq float %x, 0.0
121  %cond = select fast i1 %cmp, float 0.0, float %x
122  ret float %cond
123}
124
125; X != 0.0 ? X : 0.0 --> X
126
127define double @une_zero_nsz(double %x) {
128; CHECK-LABEL: @une_zero_nsz(
129; CHECK-NEXT:    ret double [[X:%.*]]
130;
131  %cmp = fcmp une double %x, 0.0
132  %cond = select nsz ninf i1 %cmp, double %x, double 0.0
133  ret double %cond
134}
135
136; X != 0.0 ? 0.0 : X --> 0.0
137
138define <2 x double> @une_zero_swapped_nsz(<2 x double> %x) {
139; CHECK-LABEL: @une_zero_swapped_nsz(
140; CHECK-NEXT:    ret <2 x double> zeroinitializer
141;
142  %cmp = fcmp une <2 x double> %x, <double 0.0, double 0.0>
143  %cond = select nsz <2 x i1> %cmp, <2 x double> <double 0.0, double 0.0>, <2 x double> %x
144  ret <2 x double> %cond
145}
146
147; X == Y ? X : Y --> Y
148
149define double @oeq_nsz(double %x, double %y) {
150; CHECK-LABEL: @oeq_nsz(
151; CHECK-NEXT:    ret double [[Y:%.*]]
152;
153  %cmp = fcmp oeq double %x, %y
154  %cond = select fast i1 %cmp, double %x, double %y
155  ret double %cond
156}
157
158; X == Y ? Y : X --> X
159
160define <2 x float> @oeq_swapped_nsz(<2 x float> %x, <2 x float> %y) {
161; CHECK-LABEL: @oeq_swapped_nsz(
162; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
163;
164  %cmp = fcmp oeq <2 x float> %x, %y
165  %cond = select nsz nnan <2 x i1> %cmp, <2 x float> %y, <2 x float> %x
166  ret <2 x float> %cond
167}
168
169; X != Y ? X : Y --> X
170
171define double @une_nsz(double %x, double %y) {
172; CHECK-LABEL: @une_nsz(
173; CHECK-NEXT:    ret double [[X:%.*]]
174;
175  %cmp = fcmp une double %x, %y
176  %cond = select nsz i1 %cmp, double %x, double %y
177  ret double %cond
178}
179
180; X != Y ? Y : X --> Y
181
182define <2 x double> @une_swapped_nsz(<2 x double> %x, <2 x double> %y) {
183; CHECK-LABEL: @une_swapped_nsz(
184; CHECK-NEXT:    ret <2 x double> [[Y:%.*]]
185;
186  %cmp = fcmp une <2 x double> %x, %y
187  %cond = select fast <2 x i1> %cmp, <2 x double> %y, <2 x double> %x
188  ret <2 x double> %cond
189}
190
191; Harder - mismatched zero constants (not typical due to canonicalization):
192; X != 0.0 ? X : -0.0 --> X
193
194define double @une_zero_mismatch_nsz(double %x) {
195; CHECK-LABEL: @une_zero_mismatch_nsz(
196; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[X:%.*]], 0.000000e+00
197; CHECK-NEXT:    [[COND:%.*]] = select ninf nsz i1 [[CMP]], double [[X]], double -0.000000e+00
198; CHECK-NEXT:    ret double [[COND]]
199;
200  %cmp = fcmp une double %x, 0.0
201  %cond = select nsz ninf i1 %cmp, double %x, double -0.0
202  ret double %cond
203}
204
205; Even harder - mismatched vector zero constants (not typical due to canonicalization):
206; X != 0.0 ? -0.0 : X --> 0.0
207
208define <2 x double> @une_zero_mismatch_swapped_nsz(<2 x double> %x) {
209; CHECK-LABEL: @une_zero_mismatch_swapped_nsz(
210; CHECK-NEXT:    [[CMP:%.*]] = fcmp une <2 x double> [[X:%.*]], <double -0.000000e+00, double 0.000000e+00>
211; CHECK-NEXT:    [[COND:%.*]] = select nsz <2 x i1> [[CMP]], <2 x double> <double 0.000000e+00, double -0.000000e+00>, <2 x double> [[X]]
212; CHECK-NEXT:    ret <2 x double> [[COND]]
213;
214  %cmp = fcmp une <2 x double> %x, <double -0.0, double 0.0>
215  %cond = select nsz <2 x i1> %cmp, <2 x double> <double 0.0, double -0.0>, <2 x double> %x
216  ret <2 x double> %cond
217}
218
219define double @une_could_be_negzero(double %x, double %y) {
220; CHECK-LABEL: @une_could_be_negzero(
221; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[X:%.*]], [[Y:%.*]]
222; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], double [[X]], double [[Y]]
223; CHECK-NEXT:    ret double [[COND]]
224;
225  %cmp = fcmp une double %x, %y
226  %cond = select i1 %cmp, double %x, double %y
227  ret double %cond
228}
229
230define double @une_swapped_could_be_negzero(double %x, double %y) {
231; CHECK-LABEL: @une_swapped_could_be_negzero(
232; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[X:%.*]], [[Y:%.*]]
233; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], double [[Y]], double [[X]]
234; CHECK-NEXT:    ret double [[COND]]
235;
236  %cmp = fcmp une double %x, %y
237  %cond = select i1 %cmp, double %y, double %x
238  ret double %cond
239}
240
241define double @one(double %x) {
242; CHECK-LABEL: @one(
243; CHECK-NEXT:    [[CMP:%.*]] = fcmp one double [[X:%.*]], -1.000000e+00
244; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], double [[X]], double -1.000000e+00
245; CHECK-NEXT:    ret double [[COND]]
246;
247  %cmp = fcmp one double %x, -1.0
248  %cond = select i1 %cmp, double %x, double -1.0
249  ret double %cond
250}
251
252define double @one_swapped(double %x) {
253; CHECK-LABEL: @one_swapped(
254; CHECK-NEXT:    [[CMP:%.*]] = fcmp one double [[X:%.*]], -1.000000e+00
255; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], double -1.000000e+00, double [[X]]
256; CHECK-NEXT:    ret double [[COND]]
257;
258  %cmp = fcmp one double %x, -1.0
259  %cond = select i1 %cmp, double -1.0, double %x
260  ret double %cond
261}
262
263