llvm.org GIT mirror llvm / fc21165
[ConstantFold] fp_binop AnyConstant, undef --> NaN With the updated LangRef ( D44216 / rL327138 ) in place, we can proceed with more constant folding. I'm intentionally taking the conservative path here: no matter what the constant or the FMF, we can always fold to NaN. This is because the undef operand can be chosen as NaN, and in our simplified default FP env, nothing else happens - NaN just propagates to the result. If we find some way/need to propagate undef instead, that can be added subsequently. The tests show that we always choose the same quiet NaN constant (0x7FF8000000000000 in IR text). There were suggestions to improve that with a 'NaN' string token or not always print a 64-bit hex value, but those are independent changes. We might also consider setting/propagating the payload of NaN constants as an enhancement. Differential Revision: https://reviews.llvm.org/D44308 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327208 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 2 years ago
3 changed file(s) with 38 addition(s) and 60 deletion(s). Raw diff Collapse all Expand all
10111011 // [any flop] undef, undef -> undef
10121012 if (isa(C1) && isa(C2))
10131013 return C1;
1014 // TODO: Handle one undef operand and some other constant.
1015 return nullptr;
1014 // [any flop] C, undef -> NaN
1015 // [any flop] undef, C -> NaN
1016 // We could potentially specialize NaN/Inf constants vs. 'normal'
1017 // constants (possibly differently depending on opcode and operand). This
1018 // would allow returning undef sometimes. But it is always safe to fold to
1019 // NaN because we can choose the undef operand as NaN, and any FP opcode
1020 // with a NaN operand will propagate NaN.
1021 return ConstantFP::getNaN(C1->getType());
10161022 case Instruction::BinaryOpsEnd:
10171023 llvm_unreachable("Invalid BinaryOp");
10181024 }
4646 ret float %sub
4747 }
4848
49 define float @fneg_undef(float %val) {
50 ; CHECK-LABEL: @fneg_undef(
51 ; CHECK-NEXT: ret float fsub (float -0.000000e+00, float undef)
52 ;
53 %sub = fsub float -0.0, undef
54 ret float %sub
55 }
56
57 define float @fneg_fast_undef(float %val) {
58 ; CHECK-LABEL: @fneg_fast_undef(
59 ; CHECK-NEXT: ret float fsub (float -0.000000e+00, float undef)
60 ;
61 %sub = fsub fast float -0.0, undef
62 ret float %sub
63 }
64
65 ; This folds to a constant expression, which produced 0 instructions
66 ; contrary to the expected one for negation.
67
68 define float @inconsistent_numbers_fsub_undef(float %val) {
69 ; CHECK-LABEL: @inconsistent_numbers_fsub_undef(
70 ; CHECK-NEXT: ret float fsub (float -0.000000e+00, float undef)
71 ;
72 %sub0 = fsub fast float %val, undef
73 %sub1 = fsub fast float %sub0, %val
74 ret float %sub1
75 }
76
220220
221221 define float @fadd_undef_op0_nnan_constant(float %x) {
222222 ; CHECK-LABEL: @fadd_undef_op0_nnan_constant(
223 ; CHECK-NEXT: ret float fadd (float undef, float 1.000000e+00)
223 ; CHECK-NEXT: ret float 0x7FF8000000000000
224224 ;
225225 %r = fadd nnan float undef, 1.0
226226 ret float %r
228228
229229 define float @fadd_undef_op1_constant(float %x) {
230230 ; CHECK-LABEL: @fadd_undef_op1_constant(
231 ; CHECK-NEXT: ret float fadd (float 2.000000e+00, float undef)
231 ; CHECK-NEXT: ret float 0x7FF8000000000000
232232 ;
233233 %r = fadd float 2.0, undef
234234 ret float %r
236236
237237 define float @fsub_undef_op0_fast_constant(float %x) {
238238 ; CHECK-LABEL: @fsub_undef_op0_fast_constant(
239 ; CHECK-NEXT: ret float fsub (float undef, float 3.000000e+00)
239 ; CHECK-NEXT: ret float 0x7FF8000000000000
240240 ;
241241 %r = fsub fast float undef, 3.0
242242 ret float %r
244244
245245 define float @fsub_undef_op1_constant(float %x) {
246246 ; CHECK-LABEL: @fsub_undef_op1_constant(
247 ; CHECK-NEXT: ret float fsub (float 4.000000e+00, float undef)
247 ; CHECK-NEXT: ret float 0x7FF8000000000000
248248 ;
249249 %r = fsub float 4.0, undef
250250 ret float %r
252252
253253 define float @fmul_undef_op0_nnan_constant(float %x) {
254254 ; CHECK-LABEL: @fmul_undef_op0_nnan_constant(
255 ; CHECK-NEXT: ret float fmul (float undef, float 5.000000e+00)
255 ; CHECK-NEXT: ret float 0x7FF8000000000000
256256 ;
257257 %r = fmul nnan float undef, 5.0
258258 ret float %r
260260
261261 define float @fmul_undef_op1_constant(float %x) {
262262 ; CHECK-LABEL: @fmul_undef_op1_constant(
263 ; CHECK-NEXT: ret float fmul (float 6.000000e+00, float undef)
263 ; CHECK-NEXT: ret float 0x7FF8000000000000
264264 ;
265265 %r = fmul float 6.0, undef
266266 ret float %r
268268
269269 define float @fdiv_undef_op0_fast_constant(float %x) {
270270 ; CHECK-LABEL: @fdiv_undef_op0_fast_constant(
271 ; CHECK-NEXT: ret float fdiv (float undef, float 7.000000e+00)
271 ; CHECK-NEXT: ret float 0x7FF8000000000000
272272 ;
273273 %r = fdiv fast float undef, 7.0
274274 ret float %r
276276
277277 define float @fdiv_undef_op1_constant(float %x) {
278278 ; CHECK-LABEL: @fdiv_undef_op1_constant(
279 ; CHECK-NEXT: ret float fdiv (float 8.000000e+00, float undef)
279 ; CHECK-NEXT: ret float 0x7FF8000000000000
280280 ;
281281 %r = fdiv float 8.0, undef
282282 ret float %r
284284
285285 define float @frem_undef_op0_nnan_constant(float %x) {
286286 ; CHECK-LABEL: @frem_undef_op0_nnan_constant(
287 ; CHECK-NEXT: ret float frem (float undef, float 9.000000e+00)
287 ; CHECK-NEXT: ret float 0x7FF8000000000000
288288 ;
289289 %r = frem nnan float undef, 9.0
290290 ret float %r
292292
293293 define float @frem_undef_op1_constant(float %x) {
294294 ; CHECK-LABEL: @frem_undef_op1_constant(
295 ; CHECK-NEXT: ret float frem (float 1.000000e+01, float undef)
295 ; CHECK-NEXT: ret float 0x7FF8000000000000
296296 ;
297297 %r = frem float 10.0, undef
298298 ret float %r
302302
303303 define double @fadd_undef_op0_constant_nan(double %x) {
304304 ; CHECK-LABEL: @fadd_undef_op0_constant_nan(
305 ; CHECK-NEXT: ret double fadd (double undef, double 0x7FF8000000000000)
305 ; CHECK-NEXT: ret double 0x7FF8000000000000
306306 ;
307307 %r = fadd double undef, 0x7FF8000000000000
308308 ret double %r
310310
311311 define double @fadd_undef_op1_fast_constant_nan(double %x) {
312312 ; CHECK-LABEL: @fadd_undef_op1_fast_constant_nan(
313 ; CHECK-NEXT: ret double fadd (double 0xFFF0000000000001, double undef)
313 ; CHECK-NEXT: ret double 0x7FF8000000000000
314314 ;
315315 %r = fadd fast double 0xFFF0000000000001, undef
316316 ret double %r
318318
319319 define double @fsub_undef_op0_constant_nan(double %x) {
320320 ; CHECK-LABEL: @fsub_undef_op0_constant_nan(
321 ; CHECK-NEXT: ret double fsub (double undef, double 0xFFF8000000000010)
321 ; CHECK-NEXT: ret double 0x7FF8000000000000
322322 ;
323323 %r = fsub double undef, 0xFFF8000000000010
324324 ret double %r
326326
327327 define double @fsub_undef_op1_nnan_constant_nan(double %x) {
328328 ; CHECK-LABEL: @fsub_undef_op1_nnan_constant_nan(
329 ; CHECK-NEXT: ret double fsub (double 0x7FF0000000000011, double undef)
329 ; CHECK-NEXT: ret double 0x7FF8000000000000
330330 ;
331331 %r = fsub nnan double 0x7FF0000000000011, undef
332332 ret double %r
334334
335335 define double @fmul_undef_op0_constant_nan(double %x) {
336336 ; CHECK-LABEL: @fmul_undef_op0_constant_nan(
337 ; CHECK-NEXT: ret double fmul (double undef, double 0x7FF8000000000100)
337 ; CHECK-NEXT: ret double 0x7FF8000000000000
338338 ;
339339 %r = fmul double undef, 0x7FF8000000000100
340340 ret double %r
342342
343343 define double @fmul_undef_op1_fast_constant_nan(double %x) {
344344 ; CHECK-LABEL: @fmul_undef_op1_fast_constant_nan(
345 ; CHECK-NEXT: ret double fmul (double 0xFFF0000000000101, double undef)
345 ; CHECK-NEXT: ret double 0x7FF8000000000000
346346 ;
347347 %r = fmul fast double 0xFFF0000000000101, undef
348348 ret double %r
350350
351351 define double @fdiv_undef_op0_constant_nan(double %x) {
352352 ; CHECK-LABEL: @fdiv_undef_op0_constant_nan(
353 ; CHECK-NEXT: ret double fdiv (double undef, double 0xFFF8000000000110)
353 ; CHECK-NEXT: ret double 0x7FF8000000000000
354354 ;
355355 %r = fdiv double undef, 0xFFF8000000000110
356356 ret double %r
358358
359359 define double @fdiv_undef_op1_nnan_constant_nan(double %x) {
360360 ; CHECK-LABEL: @fdiv_undef_op1_nnan_constant_nan(
361 ; CHECK-NEXT: ret double fdiv (double 0x7FF0000000000111, double undef)
361 ; CHECK-NEXT: ret double 0x7FF8000000000000
362362 ;
363363 %r = fdiv nnan double 0x7FF0000000000111, undef
364364 ret double %r
366366
367367 define double @frem_undef_op0_constant_nan(double %x) {
368368 ; CHECK-LABEL: @frem_undef_op0_constant_nan(
369 ; CHECK-NEXT: ret double frem (double undef, double 0x7FF8000000001000)
369 ; CHECK-NEXT: ret double 0x7FF8000000000000
370370 ;
371371 %r = frem double undef, 0x7FF8000000001000
372372 ret double %r
374374
375375 define double @frem_undef_op1_fast_constant_nan(double %x) {
376376 ; CHECK-LABEL: @frem_undef_op1_fast_constant_nan(
377 ; CHECK-NEXT: ret double frem (double 0xFFF0000000001001, double undef)
377 ; CHECK-NEXT: ret double 0x7FF8000000000000
378378 ;
379379 %r = frem fast double 0xFFF0000000001001, undef
380380 ret double %r
384384
385385 define double @fadd_undef_op0_constant_inf(double %x) {
386386 ; CHECK-LABEL: @fadd_undef_op0_constant_inf(
387 ; CHECK-NEXT: ret double fadd (double undef, double 0x7FF0000000000000)
387 ; CHECK-NEXT: ret double 0x7FF8000000000000
388388 ;
389389 %r = fadd double undef, 0x7FF0000000000000
390390 ret double %r
392392
393393 define double @fadd_undef_op1_fast_constant_inf(double %x) {
394394 ; CHECK-LABEL: @fadd_undef_op1_fast_constant_inf(
395 ; CHECK-NEXT: ret double fadd (double 0xFFF0000000000000, double undef)
395 ; CHECK-NEXT: ret double 0x7FF8000000000000
396396 ;
397397 %r = fadd fast double 0xFFF0000000000000, undef
398398 ret double %r
400400
401401 define double @fsub_undef_op0_constant_inf(double %x) {
402402 ; CHECK-LABEL: @fsub_undef_op0_constant_inf(
403 ; CHECK-NEXT: ret double fsub (double undef, double 0xFFF0000000000000)
403 ; CHECK-NEXT: ret double 0x7FF8000000000000
404404 ;
405405 %r = fsub double undef, 0xFFF0000000000000
406406 ret double %r
408408
409409 define double @fsub_undef_op1_ninf_constant_inf(double %x) {
410410 ; CHECK-LABEL: @fsub_undef_op1_ninf_constant_inf(
411 ; CHECK-NEXT: ret double fsub (double 0x7FF0000000000000, double undef)
411 ; CHECK-NEXT: ret double 0x7FF8000000000000
412412 ;
413413 %r = fsub ninf double 0x7FF0000000000000, undef
414414 ret double %r
416416
417417 define double @fmul_undef_op0_constant_inf(double %x) {
418418 ; CHECK-LABEL: @fmul_undef_op0_constant_inf(
419 ; CHECK-NEXT: ret double fmul (double undef, double 0x7FF0000000000000)
419 ; CHECK-NEXT: ret double 0x7FF8000000000000
420420 ;
421421 %r = fmul double undef, 0x7FF0000000000000
422422 ret double %r
424424
425425 define double @fmul_undef_op1_fast_constant_inf(double %x) {
426426 ; CHECK-LABEL: @fmul_undef_op1_fast_constant_inf(
427 ; CHECK-NEXT: ret double fmul (double 0xFFF0000000000000, double undef)
427 ; CHECK-NEXT: ret double 0x7FF8000000000000
428428 ;
429429 %r = fmul fast double 0xFFF0000000000000, undef
430430 ret double %r
432432
433433 define double @fdiv_undef_op0_constant_inf(double %x) {
434434 ; CHECK-LABEL: @fdiv_undef_op0_constant_inf(
435 ; CHECK-NEXT: ret double fdiv (double undef, double 0xFFF0000000000000)
435 ; CHECK-NEXT: ret double 0x7FF8000000000000
436436 ;
437437 %r = fdiv double undef, 0xFFF0000000000000
438438 ret double %r
440440
441441 define double @fdiv_undef_op1_ninf_constant_inf(double %x) {
442442 ; CHECK-LABEL: @fdiv_undef_op1_ninf_constant_inf(
443 ; CHECK-NEXT: ret double fdiv (double 0x7FF0000000000000, double undef)
443 ; CHECK-NEXT: ret double 0x7FF8000000000000
444444 ;
445445 %r = fdiv ninf double 0x7FF0000000000000, undef
446446 ret double %r
448448
449449 define double @frem_undef_op0_constant_inf(double %x) {
450450 ; CHECK-LABEL: @frem_undef_op0_constant_inf(
451 ; CHECK-NEXT: ret double frem (double undef, double 0x7FF0000000000000)
451 ; CHECK-NEXT: ret double 0x7FF8000000000000
452452 ;
453453 %r = frem double undef, 0x7FF0000000000000
454454 ret double %r
456456
457457 define double @frem_undef_op1_fast_constant_inf(double %x) {
458458 ; CHECK-LABEL: @frem_undef_op1_fast_constant_inf(
459 ; CHECK-NEXT: ret double frem (double 0xFFF0000000000000, double undef)
459 ; CHECK-NEXT: ret double 0x7FF8000000000000
460460 ;
461461 %r = frem fast double 0xFFF0000000000000, undef
462462 ret double %r