[SDAG] fold fsub -0.0, undef to undef rather than NaN
A question about this behavior came up on llvm-dev:
http://lists.llvm.org/pipermail/llvm-dev/2020-February/139003.html
...and as part of backend improvements in D73978.
We decided not to implement a more general change that would have
folded any FP binop with nearly arbitrary constant + undef operand
to undef because that is not theoretically correct (even if it is
practically correct).
This is the SDAG-equivalent to the IR change in D74713.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index e809816..d2db4bc 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5112,8 +5112,13 @@
}
switch (Opcode) {
- case ISD::FADD:
case ISD::FSUB:
+ // -0.0 - undef --> undef (consistent with "fneg undef")
+ if (N1CFP && N1CFP->getValueAPF().isNegZero() && N2.isUndef())
+ return getUNDEF(VT);
+ LLVM_FALLTHROUGH;
+
+ case ISD::FADD:
case ISD::FMUL:
case ISD::FDIV:
case ISD::FREM:
diff --git a/llvm/test/CodeGen/X86/vec_fneg.ll b/llvm/test/CodeGen/X86/vec_fneg.ll
index 4d5539f..c3c1932 100644
--- a/llvm/test/CodeGen/X86/vec_fneg.ll
+++ b/llvm/test/CodeGen/X86/vec_fneg.ll
@@ -76,12 +76,10 @@
define <4 x float> @fsub_neg0_undef_elts_undef(<4 x float> %x) {
; X32-SSE-LABEL: fsub_neg0_undef_elts_undef:
; X32-SSE: # %bb.0:
-; X32-SSE-NEXT: movaps {{.*#+}} xmm0 = <NaN,u,u,NaN>
; X32-SSE-NEXT: retl
;
; X64-SSE-LABEL: fsub_neg0_undef_elts_undef:
; X64-SSE: # %bb.0:
-; X64-SSE-NEXT: movaps {{.*#+}} xmm0 = <NaN,u,u,NaN>
; X64-SSE-NEXT: retq
%r = fsub <4 x float> <float -0.0, float undef, float undef, float -0.0>, undef
ret <4 x float> %r