1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4 ; X == 42.0 ? X : 42.0 --> 42.0
6 define double @oeq(double %x) {
8 ; CHECK-NEXT: ret double 4.200000e+01
10 %cmp = fcmp oeq double %x, 42.0
11 %cond = select i1 %cmp, double %x, double 42.0
15 ; X == 42.0 ? 42.0 : X --> X
17 define float @oeq_swapped(float %x) {
18 ; CHECK-LABEL: @oeq_swapped(
19 ; CHECK-NEXT: ret float [[X:%.*]]
21 %cmp = fcmp oeq float %x, 42.0
22 %cond = select i1 %cmp, float 42.0, float %x
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.
29 ; X != 42.0 ? X : 42.0 --> X
31 define double @une(double %x) {
33 ; CHECK-NEXT: ret double [[X:%.*]]
35 %cmp = fcmp une double %x, 42.0
36 %cond = select i1 %cmp, double %x, double 42.0
40 ; X != 42.0 ? 42.0 : X --> 42.0
42 define double @une_swapped(double %x) {
43 ; CHECK-LABEL: @une_swapped(
44 ; CHECK-NEXT: ret double 4.200000e+01
46 %cmp = fcmp une double %x, 42.0
47 %cond = select i1 %cmp, double 42.0, double %x
51 ; X == 0.0 ? X : 0.0 --> ? (X could be -0.0)
53 define 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]]
59 %cmp = fcmp oeq double %x, 0.0
60 %cond = select i1 %cmp, double %x, double 0.0
64 ; X == 0.0 ? 0.0 : X --> ? (change sign if X is -0.0)
66 define 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]]
72 %cmp = fcmp oeq float %x, 0.0
73 %cond = select i1 %cmp, float 0.0, float %x
77 ; X != 0.0 ? X : -0.0 --> ? (change sign if X is 0.0)
79 define 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]]
85 %cmp = fcmp une double %x, 0.0
86 %cond = select i1 %cmp, double %x, double -0.0
90 ; X != 0.0 ? -0.0 : X --> ? (X could be 0.0)
92 define 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]]
98 %cmp = fcmp une double %x, 0.0
99 %cond = select i1 %cmp, double -0.0, double %x
103 ; X == 0.0 ? X : 0.0 --> 0.0
105 define double @oeq_zero_nsz(double %x) {
106 ; CHECK-LABEL: @oeq_zero_nsz(
107 ; CHECK-NEXT: ret double 0.000000e+00
109 %cmp = fcmp oeq double %x, 0.0
110 %cond = select nsz i1 %cmp, double %x, double 0.0
114 ; X == 0.0 ? 0.0 : X --> X
116 define float @oeq_zero_swapped_nsz(float %x) {
117 ; CHECK-LABEL: @oeq_zero_swapped_nsz(
118 ; CHECK-NEXT: ret float [[X:%.*]]
120 %cmp = fcmp oeq float %x, 0.0
121 %cond = select fast i1 %cmp, float 0.0, float %x
125 ; X != 0.0 ? X : 0.0 --> X
127 define double @une_zero_nsz(double %x) {
128 ; CHECK-LABEL: @une_zero_nsz(
129 ; CHECK-NEXT: ret double [[X:%.*]]
131 %cmp = fcmp une double %x, 0.0
132 %cond = select nsz ninf i1 %cmp, double %x, double 0.0
136 ; X != 0.0 ? 0.0 : X --> 0.0
138 define <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
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
147 ; X == Y ? X : Y --> Y
149 define double @oeq_nsz(double %x, double %y) {
150 ; CHECK-LABEL: @oeq_nsz(
151 ; CHECK-NEXT: ret double [[Y:%.*]]
153 %cmp = fcmp oeq double %x, %y
154 %cond = select fast i1 %cmp, double %x, double %y
158 ; X == Y ? Y : X --> X
160 define <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:%.*]]
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
169 ; X != Y ? X : Y --> X
171 define double @une_nsz(double %x, double %y) {
172 ; CHECK-LABEL: @une_nsz(
173 ; CHECK-NEXT: ret double [[X:%.*]]
175 %cmp = fcmp une double %x, %y
176 %cond = select nsz i1 %cmp, double %x, double %y
180 ; X != Y ? Y : X --> Y
182 define <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:%.*]]
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
191 ; Harder - mismatched zero constants (not typical due to canonicalization):
192 ; X != 0.0 ? X : -0.0 --> X
194 define 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]]
200 %cmp = fcmp une double %x, 0.0
201 %cond = select nsz ninf i1 %cmp, double %x, double -0.0
205 ; Even harder - mismatched vector zero constants (not typical due to canonicalization):
206 ; X != 0.0 ? -0.0 : X --> 0.0
208 define <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]]
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
219 define 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]]
225 %cmp = fcmp une double %x, %y
226 %cond = select i1 %cmp, double %x, double %y
230 define 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]]
236 %cmp = fcmp une double %x, %y
237 %cond = select i1 %cmp, double %y, double %x
241 define double @one(double %x) {
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]]
247 %cmp = fcmp one double %x, -1.0
248 %cond = select i1 %cmp, double %x, double -1.0
252 define 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]]
258 %cmp = fcmp one double %x, -1.0
259 %cond = select i1 %cmp, double -1.0, double %x