llvm.org GIT mirror llvm / 9dd21f4
Added TLI hook for isFPExtFree. Some of the FMA combine heuristics are now guarded with that hook. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225795 91177308-0d34-0410-b5e6-96231b3b80d8 Olivier Sallenave 5 years ago
4 changed file(s) with 87 addition(s) and 65 deletion(s). Raw diff Collapse all Expand all
14991499 return isZExtFree(Val.getValueType(), VT2);
15001500 }
15011501
1502 /// Return true if an fpext operation is free (for instance, because
1503 /// single-precision floating-point numbers are implicitly extended to
1504 /// double-precision).
1505 virtual bool isFPExtFree(EVT VT) const {
1506 assert(VT.isFloatingPoint());
1507 return false;
1508 }
1509
15021510 /// Return true if an fneg operation is free to the point where it is never
15031511 /// worthwhile to replace it with a bitwise operation.
15041512 virtual bool isFNegFree(EVT VT) const {
69566956 return DAG.getNode(ISD::FMA, SDLoc(N), VT,
69576957 N1.getOperand(0), N1.getOperand(1), N0);
69586958
6959 // More folding opportunities when target permits.
6960 if (TLI.enableAggressiveFMAFusion(VT)) {
6961 // fold (fadd (fma x, y, (fmul u, v)), z) -> (fma x, y (fma u, v, z))
6962 if (N0.getOpcode() == ISD::FMA &&
6963 N0.getOperand(2).getOpcode() == ISD::FMUL)
6964 return DAG.getNode(ISD::FMA, SDLoc(N), VT,
6965 N0.getOperand(0), N0.getOperand(1),
6966 DAG.getNode(ISD::FMA, SDLoc(N), VT,
6967 N0.getOperand(2).getOperand(0),
6968 N0.getOperand(2).getOperand(1),
6969 N1));
6970
6971 // fold (fadd x, (fma y, z, (fmul u, v)) -> (fma y, z (fma u, v, x))
6972 if (N1->getOpcode() == ISD::FMA &&
6973 N1.getOperand(2).getOpcode() == ISD::FMUL)
6974 return DAG.getNode(ISD::FMA, SDLoc(N), VT,
6975 N1.getOperand(0), N1.getOperand(1),
6976 DAG.getNode(ISD::FMA, SDLoc(N), VT,
6977 N1.getOperand(2).getOperand(0),
6978 N1.getOperand(2).getOperand(1),
6979 N0));
6980
6981 // Remove FP_EXTEND when there is an opportunity to combine. This is
6982 // legal here since extra precision is allowed.
6983
6984 // fold (fadd (fpext (fmul x, y)), z) -> (fma x, y, z)
6959 // When FP_EXTEND nodes are free on the target, and there is an opportunity
6960 // to combine into FMA, arrange such nodes accordingly.
6961 if (TLI.isFPExtFree(VT)) {
6962
6963 // fold (fadd (fpext (fmul x, y)), z) -> (fma (fpext x), (fpext y), z)
69856964 if (N0.getOpcode() == ISD::FP_EXTEND) {
69866965 SDValue N00 = N0.getOperand(0);
69876966 if (N00.getOpcode() == ISD::FMUL)
69926971 N00.getOperand(1)), N1);
69936972 }
69946973
6995 // fold (fadd x, (fpext (fmul y, z)), z) -> (fma y, z, x)
6974 // fold (fadd x, (fpext (fmul y, z)), z) -> (fma (fpext y), (fpext z), x)
69966975 // Note: Commutes FADD operands.
69976976 if (N1.getOpcode() == ISD::FP_EXTEND) {
69986977 SDValue N10 = N1.getOperand(0);
70046983 N10.getOperand(1)), N0);
70056984 }
70066985 }
6986
6987 // More folding opportunities when target permits.
6988 if (TLI.enableAggressiveFMAFusion(VT)) {
6989
6990 // fold (fadd (fma x, y, (fmul u, v)), z) -> (fma x, y (fma u, v, z))
6991 if (N0.getOpcode() == ISD::FMA &&
6992 N0.getOperand(2).getOpcode() == ISD::FMUL)
6993 return DAG.getNode(ISD::FMA, SDLoc(N), VT,
6994 N0.getOperand(0), N0.getOperand(1),
6995 DAG.getNode(ISD::FMA, SDLoc(N), VT,
6996 N0.getOperand(2).getOperand(0),
6997 N0.getOperand(2).getOperand(1),
6998 N1));
6999
7000 // fold (fadd x, (fma y, z, (fmul u, v)) -> (fma y, z (fma u, v, x))
7001 if (N1->getOpcode() == ISD::FMA &&
7002 N1.getOperand(2).getOpcode() == ISD::FMUL)
7003 return DAG.getNode(ISD::FMA, SDLoc(N), VT,
7004 N1.getOperand(0), N1.getOperand(1),
7005 DAG.getNode(ISD::FMA, SDLoc(N), VT,
7006 N1.getOperand(2).getOperand(0),
7007 N1.getOperand(2).getOperand(1),
7008 N0));
7009 }
70077010 }
70087011
70097012 return SDValue();
70987101 DAG.getNode(ISD::FNEG, dl, VT, N1));
70997102 }
71007103
7101 // More folding opportunities when target permits.
7102 if (TLI.enableAggressiveFMAFusion(VT)) {
7103
7104 // fold (fsub (fma x, y, (fmul u, v)), z)
7105 // -> (fma x, y (fma u, v, (fneg z)))
7106 if (N0.getOpcode() == ISD::FMA &&
7107 N0.getOperand(2).getOpcode() == ISD::FMUL)
7108 return DAG.getNode(ISD::FMA, SDLoc(N), VT,
7109 N0.getOperand(0), N0.getOperand(1),
7110 DAG.getNode(ISD::FMA, SDLoc(N), VT,
7111 N0.getOperand(2).getOperand(0),
7112 N0.getOperand(2).getOperand(1),
7113 DAG.getNode(ISD::FNEG, SDLoc(N), VT,
7114 N1)));
7115
7116 // fold (fsub x, (fma y, z, (fmul u, v)))
7117 // -> (fma (fneg y), z, (fma (fneg u), v, x))
7118 if (N1.getOpcode() == ISD::FMA &&
7119 N1.getOperand(2).getOpcode() == ISD::FMUL) {
7120 SDValue N20 = N1.getOperand(2).getOperand(0);
7121 SDValue N21 = N1.getOperand(2).getOperand(1);
7122 return DAG.getNode(ISD::FMA, SDLoc(N), VT,
7123 DAG.getNode(ISD::FNEG, SDLoc(N), VT,
7124 N1.getOperand(0)),
7125 N1.getOperand(1),
7126 DAG.getNode(ISD::FMA, SDLoc(N), VT,
7127 DAG.getNode(ISD::FNEG, SDLoc(N), VT,
7128 N20),
7129 N21, N0));
7130 }
7131
7132 // Remove FP_EXTEND when there is an opportunity to combine. This is
7133 // legal here since extra precision is allowed.
7134
7135 // fold (fsub (fpext (fmul x, y)), z) -> (fma x, y, (fneg z))
7104 // When FP_EXTEND nodes are free on the target, and there is an opportunity
7105 // to combine into FMA, arrange such nodes accordingly.
7106 if (TLI.isFPExtFree(VT)) {
7107
7108 // fold (fsub (fpext (fmul x, y)), z)
7109 // -> (fma (fpext x), (fpext y), (fneg z))
71367110 if (N0.getOpcode() == ISD::FP_EXTEND) {
71377111 SDValue N00 = N0.getOperand(0);
71387112 if (N00.getOpcode() == ISD::FMUL)
71447118 DAG.getNode(ISD::FNEG, SDLoc(N), VT, N1));
71457119 }
71467120
7147 // fold (fsub x, (fpext (fmul y, z))) -> (fma (fneg y), z, x)
7121 // fold (fsub x, (fpext (fmul y, z)))
7122 // -> (fma (fneg (fpext y)), (fpext z), x)
71487123 // Note: Commutes FSUB operands.
71497124 if (N1.getOpcode() == ISD::FP_EXTEND) {
71507125 SDValue N10 = N1.getOperand(0);
71597134 }
71607135
71617136 // fold (fsub (fpext (fneg (fmul, x, y))), z)
7162 // -> (fma (fneg x), y, (fneg z))
7137 // -> (fma (fneg (fpext x)), (fpext y), (fneg z))
71637138 if (N0.getOpcode() == ISD::FP_EXTEND) {
71647139 SDValue N00 = N0.getOperand(0);
71657140 if (N00.getOpcode() == ISD::FNEG) {
71777152 }
71787153
71797154 // fold (fsub (fneg (fpext (fmul, x, y))), z)
7180 // -> (fma (fneg x), y, (fneg z))
7155 // -> (fma (fneg (fpext x)), (fpext y), (fneg z))
71817156 if (N0.getOpcode() == ISD::FNEG) {
71827157 SDValue N00 = N0.getOperand(0);
71837158 if (N00.getOpcode() == ISD::FP_EXTEND) {
71927167 DAG.getNode(ISD::FNEG, dl, VT, N1));
71937168 }
71947169 }
7170 }
7171 }
7172
7173 // More folding opportunities when target permits.
7174 if (TLI.enableAggressiveFMAFusion(VT)) {
7175
7176 // fold (fsub (fma x, y, (fmul u, v)), z)
7177 // -> (fma x, y (fma u, v, (fneg z)))
7178 if (N0.getOpcode() == ISD::FMA &&
7179 N0.getOperand(2).getOpcode() == ISD::FMUL)
7180 return DAG.getNode(ISD::FMA, SDLoc(N), VT,
7181 N0.getOperand(0), N0.getOperand(1),
7182 DAG.getNode(ISD::FMA, SDLoc(N), VT,
7183 N0.getOperand(2).getOperand(0),
7184 N0.getOperand(2).getOperand(1),
7185 DAG.getNode(ISD::FNEG, SDLoc(N), VT,
7186 N1)));
7187
7188 // fold (fsub x, (fma y, z, (fmul u, v)))
7189 // -> (fma (fneg y), z, (fma (fneg u), v, x))
7190 if (N1.getOpcode() == ISD::FMA &&
7191 N1.getOperand(2).getOpcode() == ISD::FMUL) {
7192 SDValue N20 = N1.getOperand(2).getOperand(0);
7193 SDValue N21 = N1.getOperand(2).getOperand(1);
7194 return DAG.getNode(ISD::FMA, SDLoc(N), VT,
7195 DAG.getNode(ISD::FNEG, SDLoc(N), VT,
7196 N1.getOperand(0)),
7197 N1.getOperand(1),
7198 DAG.getNode(ISD::FMA, SDLoc(N), VT,
7199 DAG.getNode(ISD::FNEG, SDLoc(N), VT,
7200 N20),
7201 N21, N0));
71957202 }
71967203 }
71977204 }
98169816 return TargetLowering::isZExtFree(Val, VT2);
98179817 }
98189818
9819 bool PPCTargetLowering::isFPExtFree(EVT VT) const {
9820 assert(VT.isFloatingPoint());
9821 return true;
9822 }
9823
98199824 bool PPCTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
98209825 return isInt<16>(Imm) || isUInt<16>(Imm);
98219826 }
526526 bool isTruncateFree(EVT VT1, EVT VT2) const override;
527527
528528 bool isZExtFree(SDValue Val, EVT VT2) const override;
529
530 bool isFPExtFree(EVT VT) const override;
529531
530532 /// \brief Returns true if it is beneficial to convert a load of a constant
531533 /// to just the constant itself.