@@ -59,6 +59,20 @@ using namespace llvm;
59
59
60
60
namespace {
61
61
62
+ // / Keeps track of state when getting the sign of a floating-point value as an
63
+ // / integer.
64
+ struct FloatSignAsInt {
65
+ EVT FloatVT;
66
+ SDValue Chain;
67
+ SDValue FloatPtr;
68
+ SDValue IntPtr;
69
+ MachinePointerInfo IntPointerInfo;
70
+ MachinePointerInfo FloatPointerInfo;
71
+ SDValue IntValue;
72
+ APInt SignMask;
73
+ uint8_t SignBit;
74
+ };
75
+
62
76
// ===----------------------------------------------------------------------===//
63
77
// / This takes an arbitrary SelectionDAG as input and
64
78
// / hacks on it until the target machine can handle it. This involves
@@ -152,6 +166,10 @@ class SelectionDAGLegalize {
152
166
SDValue ExpandSCALAR_TO_VECTOR (SDNode *Node);
153
167
void ExpandDYNAMIC_STACKALLOC (SDNode *Node,
154
168
SmallVectorImpl<SDValue> &Results);
169
+ void getSignAsIntValue (FloatSignAsInt &State, const SDLoc &DL,
170
+ SDValue Value) const ;
171
+ SDValue modifySignAsInt (const FloatSignAsInt &State, const SDLoc &DL,
172
+ SDValue NewIntValue) const ;
155
173
SDValue ExpandFCOPYSIGN (SDNode *Node) const ;
156
174
SDValue ExpandFABS (SDNode *Node) const ;
157
175
SDValue ExpandFNEG (SDNode *Node) const ;
@@ -1602,14 +1620,82 @@ SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
1602
1620
return DAG.getLoad (VT, dl, StoreChain, FIPtr, PtrInfo);
1603
1621
}
1604
1622
1623
+ // / Bitcast a floating-point value to an integer value. Only bitcast the part
1624
+ // / containing the sign bit if the target has no integer value capable of
1625
+ // / holding all bits of the floating-point value.
1626
+ void SelectionDAGLegalize::getSignAsIntValue (FloatSignAsInt &State,
1627
+ const SDLoc &DL,
1628
+ SDValue Value) const {
1629
+ EVT FloatVT = Value.getValueType ();
1630
+ unsigned NumBits = FloatVT.getScalarSizeInBits ();
1631
+ State.FloatVT = FloatVT;
1632
+ EVT IVT = EVT::getIntegerVT (*DAG.getContext (), NumBits);
1633
+ // Convert to an integer of the same size.
1634
+ if (TLI.isTypeLegal (IVT)) {
1635
+ State.IntValue = DAG.getNode (ISD::BITCAST, DL, IVT, Value);
1636
+ State.SignMask = APInt::getSignMask (NumBits);
1637
+ State.SignBit = NumBits - 1 ;
1638
+ return ;
1639
+ }
1640
+
1641
+ auto &DataLayout = DAG.getDataLayout ();
1642
+ // Store the float to memory, then load the sign part out as an integer.
1643
+ MVT LoadTy = TLI.getRegisterType (MVT::i8 );
1644
+ // First create a temporary that is aligned for both the load and store.
1645
+ SDValue StackPtr = DAG.CreateStackTemporary (FloatVT, LoadTy);
1646
+ int FI = cast<FrameIndexSDNode>(StackPtr.getNode ())->getIndex ();
1647
+ // Then store the float to it.
1648
+ State.FloatPtr = StackPtr;
1649
+ MachineFunction &MF = DAG.getMachineFunction ();
1650
+ State.FloatPointerInfo = MachinePointerInfo::getFixedStack (MF, FI);
1651
+ State.Chain = DAG.getStore (DAG.getEntryNode (), DL, Value, State.FloatPtr ,
1652
+ State.FloatPointerInfo );
1653
+
1654
+ SDValue IntPtr;
1655
+ if (DataLayout.isBigEndian ()) {
1656
+ assert (FloatVT.isByteSized () && " Unsupported floating point type!" );
1657
+ // Load out a legal integer with the same sign bit as the float.
1658
+ IntPtr = StackPtr;
1659
+ State.IntPointerInfo = State.FloatPointerInfo ;
1660
+ } else {
1661
+ // Advance the pointer so that the loaded byte will contain the sign bit.
1662
+ unsigned ByteOffset = (NumBits / 8 ) - 1 ;
1663
+ IntPtr =
1664
+ DAG.getMemBasePlusOffset (StackPtr, TypeSize::getFixed (ByteOffset), DL);
1665
+ State.IntPointerInfo = MachinePointerInfo::getFixedStack (MF, FI,
1666
+ ByteOffset);
1667
+ }
1668
+
1669
+ State.IntPtr = IntPtr;
1670
+ State.IntValue = DAG.getExtLoad (ISD::EXTLOAD, DL, LoadTy, State.Chain , IntPtr,
1671
+ State.IntPointerInfo , MVT::i8 );
1672
+ State.SignMask = APInt::getOneBitSet (LoadTy.getScalarSizeInBits (), 7 );
1673
+ State.SignBit = 7 ;
1674
+ }
1675
+
1676
+ // / Replace the integer value produced by getSignAsIntValue() with a new value
1677
+ // / and cast the result back to a floating-point type.
1678
+ SDValue SelectionDAGLegalize::modifySignAsInt (const FloatSignAsInt &State,
1679
+ const SDLoc &DL,
1680
+ SDValue NewIntValue) const {
1681
+ if (!State.Chain )
1682
+ return DAG.getNode (ISD::BITCAST, DL, State.FloatVT , NewIntValue);
1683
+
1684
+ // Override the part containing the sign bit in the value stored on the stack.
1685
+ SDValue Chain = DAG.getTruncStore (State.Chain , DL, NewIntValue, State.IntPtr ,
1686
+ State.IntPointerInfo , MVT::i8 );
1687
+ return DAG.getLoad (State.FloatVT , DL, Chain, State.FloatPtr ,
1688
+ State.FloatPointerInfo );
1689
+ }
1690
+
1605
1691
SDValue SelectionDAGLegalize::ExpandFCOPYSIGN (SDNode *Node) const {
1606
1692
SDLoc DL (Node);
1607
1693
SDValue Mag = Node->getOperand (0 );
1608
1694
SDValue Sign = Node->getOperand (1 );
1609
1695
1610
1696
// Get sign bit into an integer value.
1611
1697
FloatSignAsInt SignAsInt;
1612
- DAG. getSignAsIntValue (SignAsInt, DL, Sign);
1698
+ getSignAsIntValue (SignAsInt, DL, Sign);
1613
1699
1614
1700
EVT IntVT = SignAsInt.IntValue .getValueType ();
1615
1701
SDValue SignMask = DAG.getConstant (SignAsInt.SignMask , DL, IntVT);
@@ -1630,7 +1716,7 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node) const {
1630
1716
1631
1717
// Transform Mag value to integer, and clear the sign bit.
1632
1718
FloatSignAsInt MagAsInt;
1633
- DAG. getSignAsIntValue (MagAsInt, DL, Mag);
1719
+ getSignAsIntValue (MagAsInt, DL, Mag);
1634
1720
EVT MagVT = MagAsInt.IntValue .getValueType ();
1635
1721
SDValue ClearSignMask = DAG.getConstant (~MagAsInt.SignMask , DL, MagVT);
1636
1722
SDValue ClearedSign = DAG.getNode (ISD::AND, DL, MagVT, MagAsInt.IntValue ,
@@ -1660,14 +1746,14 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node) const {
1660
1746
SDValue CopiedSign = DAG.getNode (ISD::OR, DL, MagVT, ClearedSign, SignBit,
1661
1747
SDNodeFlags::Disjoint);
1662
1748
1663
- return DAG. modifySignAsInt (MagAsInt, DL, CopiedSign);
1749
+ return modifySignAsInt (MagAsInt, DL, CopiedSign);
1664
1750
}
1665
1751
1666
1752
SDValue SelectionDAGLegalize::ExpandFNEG (SDNode *Node) const {
1667
1753
// Get the sign bit as an integer.
1668
1754
SDLoc DL (Node);
1669
1755
FloatSignAsInt SignAsInt;
1670
- DAG. getSignAsIntValue (SignAsInt, DL, Node->getOperand (0 ));
1756
+ getSignAsIntValue (SignAsInt, DL, Node->getOperand (0 ));
1671
1757
EVT IntVT = SignAsInt.IntValue .getValueType ();
1672
1758
1673
1759
// Flip the sign.
@@ -1676,7 +1762,7 @@ SDValue SelectionDAGLegalize::ExpandFNEG(SDNode *Node) const {
1676
1762
DAG.getNode (ISD::XOR, DL, IntVT, SignAsInt.IntValue , SignMask);
1677
1763
1678
1764
// Convert back to float.
1679
- return DAG. modifySignAsInt (SignAsInt, DL, SignFlip);
1765
+ return modifySignAsInt (SignAsInt, DL, SignFlip);
1680
1766
}
1681
1767
1682
1768
SDValue SelectionDAGLegalize::ExpandFABS (SDNode *Node) const {
@@ -1692,12 +1778,12 @@ SDValue SelectionDAGLegalize::ExpandFABS(SDNode *Node) const {
1692
1778
1693
1779
// Transform value to integer, clear the sign bit and transform back.
1694
1780
FloatSignAsInt ValueAsInt;
1695
- DAG. getSignAsIntValue (ValueAsInt, DL, Value);
1781
+ getSignAsIntValue (ValueAsInt, DL, Value);
1696
1782
EVT IntVT = ValueAsInt.IntValue .getValueType ();
1697
1783
SDValue ClearSignMask = DAG.getConstant (~ValueAsInt.SignMask , DL, IntVT);
1698
1784
SDValue ClearedSign = DAG.getNode (ISD::AND, DL, IntVT, ValueAsInt.IntValue ,
1699
1785
ClearSignMask);
1700
- return DAG. modifySignAsInt (ValueAsInt, DL, ClearedSign);
1786
+ return modifySignAsInt (ValueAsInt, DL, ClearedSign);
1701
1787
}
1702
1788
1703
1789
void SelectionDAGLegalize::ExpandDYNAMIC_STACKALLOC (SDNode* Node,
0 commit comments