diff options
author | Sanjay Patel <spatel@rotateright.com> | 2018-05-21 23:54:19 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2018-05-21 23:54:19 +0000 |
commit | 17a870f07cf41372fe85c603e2338f605b3f196b (patch) | |
tree | 5e14280f606e26f12354e2da6b810980eab6fc20 /llvm/lib/CodeGen | |
parent | 5cb2e30c9805e175739cfd80a94f8022a8a84b64 (diff) | |
download | bcm5719-llvm-17a870f07cf41372fe85c603e2338f605b3f196b.tar.gz bcm5719-llvm-17a870f07cf41372fe85c603e2338f605b3f196b.zip |
[DAG] fold FP binops with undef operands to NaN
This is the FP sibling of D43141 with the corresponding IR change in rL327212.
We can't propagate undef here because if a variable operand is a NaN, these
binops must propagate NaN. Neither global nor node-level fast-math makes a
difference. If we have 'nnan', I think later folds can turn the NaN into undef.
The tests in X86/fp-undef.ll are meant to be the definitive verification for
these folds - everything reduces identically now.
The other test changes are collateral damage. They may need to be altered to
preserve their intent.
Differential Revision: https://reviews.llvm.org/D47026
llvm-svn: 332920
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 8f74d6a2a71..39fd95e7d2c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4767,6 +4767,18 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT, } } + // Any FP binop with an undef operand is folded to NaN. This matches the + // behavior of the IR optimizer. + switch (Opcode) { + case ISD::FADD: + case ISD::FSUB: + case ISD::FMUL: + case ISD::FDIV: + case ISD::FREM: + if (N1.isUndef() || N2.isUndef()) + return getConstantFP(APFloat::getNaN(EVTToAPFloatSemantics(VT)), DL, VT); + } + // Canonicalize an UNDEF to the RHS, even over a constant. if (N1.isUndef()) { if (TLI->isCommutativeBinOp(Opcode)) { @@ -4776,9 +4788,6 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT, case ISD::FP_ROUND_INREG: case ISD::SIGN_EXTEND_INREG: case ISD::SUB: - case ISD::FSUB: - case ISD::FDIV: - case ISD::FREM: return getUNDEF(VT); // fold op(undef, arg2) -> undef case ISD::UDIV: case ISD::SDIV: @@ -4813,14 +4822,6 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT, case ISD::SRL: case ISD::SHL: return getUNDEF(VT); // fold op(arg1, undef) -> undef - case ISD::FADD: - case ISD::FSUB: - case ISD::FMUL: - case ISD::FDIV: - case ISD::FREM: - if (getTarget().Options.UnsafeFPMath) - return N2; - break; case ISD::MUL: case ISD::AND: return getConstant(0, DL, VT); // fold op(arg1, undef) -> 0 |