diff options
| author | Luís Marques <luismarques@lowrisc.org> | 2019-11-24 15:23:29 +0000 |
|---|---|---|
| committer | Luís Marques <luismarques@lowrisc.org> | 2019-11-26 15:22:55 +0000 |
| commit | 6fd4c42fa815952b29bee573068d60d13f7c9f37 (patch) | |
| tree | 81e22f97305c6bd803ee5ebbf46ebaa77808133d /llvm/lib/CodeGen/SelectionDAG | |
| parent | d7be3eab5c0e1598e919973ed68a200997a4734a (diff) | |
| download | bcm5719-llvm-6fd4c42fa815952b29bee573068d60d13f7c9f37.tar.gz bcm5719-llvm-6fd4c42fa815952b29bee573068d60d13f7c9f37.zip | |
[LegalizeTypes][RISCV] Soften FCOPYSIGN operand
Summary: Adds support for softening FCOPYSIGN operands.
Adds RISC-V tests that exercise the new softening code.
Reviewers: asb, lenary, efriedma
Reviewed By: efriedma
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D70679
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp | 35 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 1 |
2 files changed, 36 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index c4a74d5c1c7..8dbff7d2735 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -854,6 +854,7 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) { case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break; case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break; case ISD::STORE: Res = SoftenFloatOp_STORE(N, OpNo); break; + case ISD::FCOPYSIGN: Res = SoftenFloatOp_FCOPYSIGN(N); break; } // If the result is null, the sub-method took care of registering results etc. @@ -1036,6 +1037,40 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) { ST->getMemOperand()); } +SDValue DAGTypeLegalizer::SoftenFloatOp_FCOPYSIGN(SDNode *N) { + SDValue LHS = N->getOperand(0); + SDValue RHS = BitConvertToInteger(N->getOperand(1)); + SDLoc dl(N); + + EVT LVT = LHS.getValueType(); + EVT ILVT = EVT::getIntegerVT(*DAG.getContext(), LVT.getSizeInBits()); + EVT RVT = RHS.getValueType(); + + unsigned LSize = LVT.getSizeInBits(); + unsigned RSize = RVT.getSizeInBits(); + + // Shift right or sign-extend it if the two operands have different types. + int SizeDiff = RSize - LSize; + if (SizeDiff > 0) { + RHS = + DAG.getNode(ISD::SRL, dl, RVT, RHS, + DAG.getConstant(SizeDiff, dl, + TLI.getShiftAmountTy(RHS.getValueType(), + DAG.getDataLayout()))); + RHS = DAG.getNode(ISD::TRUNCATE, dl, ILVT, RHS); + } else if (SizeDiff < 0) { + RHS = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, RHS); + RHS = + DAG.getNode(ISD::SHL, dl, ILVT, RHS, + DAG.getConstant(-SizeDiff, dl, + TLI.getShiftAmountTy(RHS.getValueType(), + DAG.getDataLayout()))); + } + + RHS = DAG.getBitcast(LVT, RHS); + return DAG.getNode(ISD::FCOPYSIGN, dl, LVT, LHS, RHS); +} + SDValue DAGTypeLegalizer::SoftenFloatOp_LROUND(SDNode *N) { EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index c944bda3700..89410ccd857 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -540,6 +540,7 @@ private: SDValue SoftenFloatOp_SELECT_CC(SDNode *N); SDValue SoftenFloatOp_SETCC(SDNode *N); SDValue SoftenFloatOp_STORE(SDNode *N, unsigned OpNo); + SDValue SoftenFloatOp_FCOPYSIGN(SDNode *N); //===--------------------------------------------------------------------===// // Float Expansion Support: LegalizeFloatTypes.cpp |

