@@ -142,6 +142,8 @@ class VectorLegalizer {
142
142
std::pair<SDValue, SDValue> ExpandLoad (SDNode *N);
143
143
SDValue ExpandStore (SDNode *N);
144
144
SDValue ExpandFNEG (SDNode *Node);
145
+ SDValue ExpandFABS (SDNode *Node);
146
+ SDValue ExpandFCOPYSIGN (SDNode *Node);
145
147
void ExpandFSUB (SDNode *Node, SmallVectorImpl<SDValue> &Results);
146
148
void ExpandSETCC (SDNode *Node, SmallVectorImpl<SDValue> &Results);
147
149
void ExpandBITREVERSE (SDNode *Node, SmallVectorImpl<SDValue> &Results);
@@ -942,6 +944,18 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
942
944
return ;
943
945
}
944
946
break ;
947
+ case ISD::FABS:
948
+ if (SDValue Expanded = ExpandFABS (Node)) {
949
+ Results.push_back (Expanded);
950
+ return ;
951
+ }
952
+ break ;
953
+ case ISD::FCOPYSIGN:
954
+ if (SDValue Expanded = ExpandFCOPYSIGN (Node)) {
955
+ Results.push_back (Expanded);
956
+ return ;
957
+ }
958
+ break ;
945
959
case ISD::FSUB:
946
960
ExpandFSUB (Node, Results);
947
961
return ;
@@ -1781,7 +1795,7 @@ SDValue VectorLegalizer::ExpandFNEG(SDNode *Node) {
1781
1795
1782
1796
// FIXME: The FSUB check is here to force unrolling v1f64 vectors on AArch64.
1783
1797
if (!TLI.isOperationLegalOrCustom (ISD::XOR, IntVT) ||
1784
- !TLI.isOperationLegalOrCustom (ISD::FSUB, VT))
1798
+ !( TLI.isOperationLegalOrCustom (ISD::FSUB, VT) || VT. isScalableVector () ))
1785
1799
return SDValue ();
1786
1800
1787
1801
SDLoc DL (Node);
@@ -1792,6 +1806,53 @@ SDValue VectorLegalizer::ExpandFNEG(SDNode *Node) {
1792
1806
return DAG.getNode (ISD::BITCAST, DL, VT, Xor);
1793
1807
}
1794
1808
1809
+ SDValue VectorLegalizer::ExpandFABS (SDNode *Node) {
1810
+ EVT VT = Node->getValueType (0 );
1811
+ EVT IntVT = VT.changeVectorElementTypeToInteger ();
1812
+
1813
+ // FIXME: We shouldn't restrict this to scalable vectors.
1814
+ if (!TLI.isOperationLegalOrCustom (ISD::AND, IntVT) || !VT.isScalableVector ())
1815
+ return SDValue ();
1816
+
1817
+ SDLoc DL (Node);
1818
+ SDValue Cast = DAG.getNode (ISD::BITCAST, DL, IntVT, Node->getOperand (0 ));
1819
+ SDValue ClearSignMask = DAG.getConstant (
1820
+ APInt::getSignedMaxValue (IntVT.getScalarSizeInBits ()), DL, IntVT);
1821
+ SDValue ClearedSign = DAG.getNode (ISD::AND, DL, IntVT, Cast, ClearSignMask);
1822
+ return DAG.getNode (ISD::BITCAST, DL, VT, ClearedSign);
1823
+ }
1824
+
1825
+ SDValue VectorLegalizer::ExpandFCOPYSIGN (SDNode *Node) {
1826
+ EVT VT = Node->getValueType (0 );
1827
+ EVT IntVT = VT.changeVectorElementTypeToInteger ();
1828
+
1829
+ // FIXME: We shouldn't restrict this to scalable vectors.
1830
+ if (VT != Node->getOperand (1 ).getValueType () ||
1831
+ !TLI.isOperationLegalOrCustom (ISD::AND, IntVT) ||
1832
+ !TLI.isOperationLegalOrCustom (ISD::OR, IntVT) || !VT.isScalableVector ())
1833
+ return SDValue ();
1834
+
1835
+ SDLoc DL (Node);
1836
+ SDValue Mag = DAG.getNode (ISD::BITCAST, DL, IntVT, Node->getOperand (0 ));
1837
+ SDValue Sign = DAG.getNode (ISD::BITCAST, DL, IntVT, Node->getOperand (1 ));
1838
+
1839
+ SDValue SignMask = DAG.getConstant (
1840
+ APInt::getSignMask (IntVT.getScalarSizeInBits ()), DL, IntVT);
1841
+ SDValue SignBit = DAG.getNode (ISD::AND, DL, IntVT, Sign, SignMask);
1842
+
1843
+ SDValue ClearSignMask = DAG.getConstant (
1844
+ APInt::getSignedMaxValue (IntVT.getScalarSizeInBits ()), DL, IntVT);
1845
+ SDValue ClearedSign = DAG.getNode (ISD::AND, DL, IntVT, Mag, ClearSignMask);
1846
+
1847
+ SDNodeFlags Flags;
1848
+ Flags.setDisjoint (true );
1849
+
1850
+ SDValue CopiedSign =
1851
+ DAG.getNode (ISD::OR, DL, IntVT, ClearedSign, SignBit, Flags);
1852
+
1853
+ return DAG.getNode (ISD::BITCAST, DL, VT, CopiedSign);
1854
+ }
1855
+
1795
1856
void VectorLegalizer::ExpandFSUB (SDNode *Node,
1796
1857
SmallVectorImpl<SDValue> &Results) {
1797
1858
// For floating-point values, (a-b) is the same as a+(-b). If FNEG is legal,
0 commit comments