llvm.org GIT mirror llvm / 33f09cf
[SDAG] move FP constant folding to helper function; NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355411 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 7 months ago
2 changed file(s) with 77 addition(s) and 67 deletion(s). Raw diff Collapse all Expand all
14061406 ArrayRef Ops,
14071407 const SDNodeFlags Flags = SDNodeFlags());
14081408
1409 /// Fold floating-point operations with 2 operands when both operands are
1410 /// constants and/or undefined.
1411 SDValue foldConstantFPMath(unsigned Opcode, const SDLoc &DL, EVT VT,
1412 SDValue N1, SDValue N2);
1413
14091414 /// Constant fold a setcc to true or false.
14101415 SDValue FoldSetCC(EVT VT, SDValue N1, SDValue N2, ISD::CondCode Cond,
14111416 const SDLoc &dl);
47334733 return V;
47344734 }
47354735
4736 SDValue SelectionDAG::foldConstantFPMath(unsigned Opcode, const SDLoc &DL,
4737 EVT VT, SDValue N1, SDValue N2) {
4738 auto *N1CFP = dyn_cast(N1.getNode());
4739 auto *N2CFP = dyn_cast(N2.getNode());
4740 bool HasFPExceptions = TLI->hasFloatingPointExceptions();
4741 if (N1CFP && N2CFP) {
4742 APFloat C1 = N1CFP->getValueAPF(), C2 = N2CFP->getValueAPF();
4743 APFloat::opStatus Status;
4744 switch (Opcode) {
4745 case ISD::FADD:
4746 Status = C1.add(C2, APFloat::rmNearestTiesToEven);
4747 if (!HasFPExceptions || Status != APFloat::opInvalidOp)
4748 return getConstantFP(C1, DL, VT);
4749 break;
4750 case ISD::FSUB:
4751 Status = C1.subtract(C2, APFloat::rmNearestTiesToEven);
4752 if (!HasFPExceptions || Status != APFloat::opInvalidOp)
4753 return getConstantFP(C1, DL, VT);
4754 break;
4755 case ISD::FMUL:
4756 Status = C1.multiply(C2, APFloat::rmNearestTiesToEven);
4757 if (!HasFPExceptions || Status != APFloat::opInvalidOp)
4758 return getConstantFP(C1, DL, VT);
4759 break;
4760 case ISD::FDIV:
4761 Status = C1.divide(C2, APFloat::rmNearestTiesToEven);
4762 if (!HasFPExceptions || (Status != APFloat::opInvalidOp &&
4763 Status != APFloat::opDivByZero)) {
4764 return getConstantFP(C1, DL, VT);
4765 }
4766 break;
4767 case ISD::FREM:
4768 Status = C1.mod(C2);
4769 if (!HasFPExceptions || (Status != APFloat::opInvalidOp &&
4770 Status != APFloat::opDivByZero)) {
4771 return getConstantFP(C1, DL, VT);
4772 }
4773 break;
4774 case ISD::FCOPYSIGN:
4775 C1.copySign(C2);
4776 return getConstantFP(C1, DL, VT);
4777 default: break;
4778 }
4779 }
4780 if (N1CFP && Opcode == ISD::FP_ROUND) {
4781 APFloat C1 = N1CFP->getValueAPF(); // make copy
4782 bool Unused;
4783 // This can return overflow, underflow, or inexact; we don't care.
4784 // FIXME need to be more flexible about rounding mode.
4785 (void) C1.convert(EVTToAPFloatSemantics(VT), APFloat::rmNearestTiesToEven,
4786 &Unused);
4787 return getConstantFP(C1, DL, VT);
4788 }
4789
4790 switch (Opcode) {
4791 case ISD::FADD:
4792 case ISD::FSUB:
4793 case ISD::FMUL:
4794 case ISD::FDIV:
4795 case ISD::FREM:
4796 // If both operands are undef, the result is undef. If 1 operand is undef,
4797 // the result is NaN. This should match the behavior of the IR optimizer.
4798 if (N1.isUndef() && N2.isUndef())
4799 return getUNDEF(VT);
4800 if (N1.isUndef() || N2.isUndef())
4801 return getConstantFP(APFloat::getNaN(EVTToAPFloatSemantics(VT)), DL, VT);
4802 }
4803 return SDValue();
4804 }
4805
47364806 SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
47374807 SDValue N1, SDValue N2, const SDNodeFlags Flags) {
47384808 ConstantSDNode *N1C = dyn_cast(N1);
50785148 FoldConstantArithmetic(Opcode, DL, VT, N1.getNode(), N2.getNode()))
50795149 return SV;
50805150
5081 // Constant fold FP operations.
5082 bool HasFPExceptions = TLI->hasFloatingPointExceptions();
5083 if (N1CFP) {
5084 if (N2CFP) {
5085 APFloat V1 = N1CFP->getValueAPF(), V2 = N2CFP->getValueAPF();
5086 APFloat::opStatus s;
5087 switch (Opcode) {
5088 case ISD::FADD:
5089 s = V1.add(V2, APFloat::rmNearestTiesToEven);
5090 if (!HasFPExceptions || s != APFloat::opInvalidOp)
5091 return getConstantFP(V1, DL, VT);
5092 break;
5093 case ISD::FSUB:
5094 s = V1.subtract(V2, APFloat::rmNearestTiesToEven);
5095 if (!HasFPExceptions || s!=APFloat::opInvalidOp)
5096 return getConstantFP(V1, DL, VT);
5097 break;
5098 case ISD::FMUL:
5099 s = V1.multiply(V2, APFloat::rmNearestTiesToEven);
5100 if (!HasFPExceptions || s!=APFloat::opInvalidOp)
5101 return getConstantFP(V1, DL, VT);
5102 break;
5103 case ISD::FDIV:
5104 s = V1.divide(V2, APFloat::rmNearestTiesToEven);
5105 if (!HasFPExceptions || (s!=APFloat::opInvalidOp &&
5106 s!=APFloat::opDivByZero)) {
5107 return getConstantFP(V1, DL, VT);
5108 }
5109 break;
5110 case ISD::FREM :
5111 s = V1.mod(V2);
5112 if (!HasFPExceptions || (s!=APFloat::opInvalidOp &&
5113 s!=APFloat::opDivByZero)) {
5114 return getConstantFP(V1, DL, VT);
5115 }
5116 break;
5117 case ISD::FCOPYSIGN:
5118 V1.copySign(V2);
5119 return getConstantFP(V1, DL, VT);
5120 default: break;
5121 }
5122 }
5123
5124 if (Opcode == ISD::FP_ROUND) {
5125 APFloat V = N1CFP->getValueAPF(); // make copy
5126 bool ignored;
5127 // This can return overflow, underflow, or inexact; we don't care.
5128 // FIXME need to be more flexible about rounding mode.
5129 (void)V.convert(EVTToAPFloatSemantics(VT),
5130 APFloat::rmNearestTiesToEven, &ignored);
5131 return getConstantFP(V, DL, VT);
5132 }
5133 }
5134
5135 switch (Opcode) {
5136 case ISD::FADD:
5137 case ISD::FSUB:
5138 case ISD::FMUL:
5139 case ISD::FDIV:
5140 case ISD::FREM:
5141 // If both operands are undef, the result is undef. If 1 operand is undef,
5142 // the result is NaN. This should match the behavior of the IR optimizer.
5143 if (N1.isUndef() && N2.isUndef())
5144 return getUNDEF(VT);
5145 if (N1.isUndef() || N2.isUndef())
5146 return getConstantFP(APFloat::getNaN(EVTToAPFloatSemantics(VT)), DL, VT);
5147 }
5151 if (SDValue V = foldConstantFPMath(Opcode, DL, VT, N1, N2))
5152 return V;
51485153
51495154 // Canonicalize an UNDEF to the RHS, even over a constant.
51505155 if (N1.isUndef()) {