Skip to content

Commit d74831e

Browse files
committed
Revert "[SDAG] Fix fmaximum legalization errors (#142170)"
This reverts commit 58cc167. I also made the incorrect assumption that we know both values are +/-0.0 here as well. Revert for now.
1 parent 42605b8 commit d74831e

File tree

12 files changed

+385
-1243
lines changed

12 files changed

+385
-1243
lines changed

llvm/include/llvm/CodeGen/SelectionDAG.h

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -215,20 +215,6 @@ class SDDbgInfo {
215215

216216
LLVM_ABI void checkForCycles(const SelectionDAG *DAG, bool force = false);
217217

218-
/// Keeps track of state when getting the sign of a floating-point value as an
219-
/// integer.
220-
struct FloatSignAsInt {
221-
EVT FloatVT;
222-
SDValue Chain;
223-
SDValue FloatPtr;
224-
SDValue IntPtr;
225-
MachinePointerInfo IntPointerInfo;
226-
MachinePointerInfo FloatPointerInfo;
227-
SDValue IntValue;
228-
APInt SignMask;
229-
uint8_t SignBit;
230-
};
231-
232218
/// This is used to represent a portion of an LLVM function in a low-level
233219
/// Data Dependence DAG representation suitable for instruction selection.
234220
/// This DAG is constructed as the first step of instruction selection in order
@@ -2031,16 +2017,6 @@ class SelectionDAG {
20312017
/// value types.
20322018
LLVM_ABI SDValue CreateStackTemporary(EVT VT1, EVT VT2);
20332019

2034-
/// Bitcast a floating-point value to an integer value. Only bitcast the part
2035-
/// containing the sign bit if the target has no integer value capable of
2036-
/// holding all bits of the floating-point value.
2037-
void getSignAsIntValue(FloatSignAsInt &State, const SDLoc &DL, SDValue Value);
2038-
2039-
/// Replace the integer value produced by getSignAsIntValue() with a new value
2040-
/// and cast the result back to a floating-point type.
2041-
SDValue modifySignAsInt(const FloatSignAsInt &State, const SDLoc &DL,
2042-
SDValue NewIntValue);
2043-
20442020
LLVM_ABI SDValue FoldSymbolOffset(unsigned Opcode, EVT VT,
20452021
const GlobalAddressSDNode *GA,
20462022
const SDNode *N2);

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 93 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@ using namespace llvm;
5959

6060
namespace {
6161

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+
6276
//===----------------------------------------------------------------------===//
6377
/// This takes an arbitrary SelectionDAG as input and
6478
/// hacks on it until the target machine can handle it. This involves
@@ -152,6 +166,10 @@ class SelectionDAGLegalize {
152166
SDValue ExpandSCALAR_TO_VECTOR(SDNode *Node);
153167
void ExpandDYNAMIC_STACKALLOC(SDNode *Node,
154168
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;
155173
SDValue ExpandFCOPYSIGN(SDNode *Node) const;
156174
SDValue ExpandFABS(SDNode *Node) const;
157175
SDValue ExpandFNEG(SDNode *Node) const;
@@ -1602,14 +1620,82 @@ SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
16021620
return DAG.getLoad(VT, dl, StoreChain, FIPtr, PtrInfo);
16031621
}
16041622

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+
16051691
SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node) const {
16061692
SDLoc DL(Node);
16071693
SDValue Mag = Node->getOperand(0);
16081694
SDValue Sign = Node->getOperand(1);
16091695

16101696
// Get sign bit into an integer value.
16111697
FloatSignAsInt SignAsInt;
1612-
DAG.getSignAsIntValue(SignAsInt, DL, Sign);
1698+
getSignAsIntValue(SignAsInt, DL, Sign);
16131699

16141700
EVT IntVT = SignAsInt.IntValue.getValueType();
16151701
SDValue SignMask = DAG.getConstant(SignAsInt.SignMask, DL, IntVT);
@@ -1630,7 +1716,7 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node) const {
16301716

16311717
// Transform Mag value to integer, and clear the sign bit.
16321718
FloatSignAsInt MagAsInt;
1633-
DAG.getSignAsIntValue(MagAsInt, DL, Mag);
1719+
getSignAsIntValue(MagAsInt, DL, Mag);
16341720
EVT MagVT = MagAsInt.IntValue.getValueType();
16351721
SDValue ClearSignMask = DAG.getConstant(~MagAsInt.SignMask, DL, MagVT);
16361722
SDValue ClearedSign = DAG.getNode(ISD::AND, DL, MagVT, MagAsInt.IntValue,
@@ -1660,14 +1746,14 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node) const {
16601746
SDValue CopiedSign = DAG.getNode(ISD::OR, DL, MagVT, ClearedSign, SignBit,
16611747
SDNodeFlags::Disjoint);
16621748

1663-
return DAG.modifySignAsInt(MagAsInt, DL, CopiedSign);
1749+
return modifySignAsInt(MagAsInt, DL, CopiedSign);
16641750
}
16651751

16661752
SDValue SelectionDAGLegalize::ExpandFNEG(SDNode *Node) const {
16671753
// Get the sign bit as an integer.
16681754
SDLoc DL(Node);
16691755
FloatSignAsInt SignAsInt;
1670-
DAG.getSignAsIntValue(SignAsInt, DL, Node->getOperand(0));
1756+
getSignAsIntValue(SignAsInt, DL, Node->getOperand(0));
16711757
EVT IntVT = SignAsInt.IntValue.getValueType();
16721758

16731759
// Flip the sign.
@@ -1676,7 +1762,7 @@ SDValue SelectionDAGLegalize::ExpandFNEG(SDNode *Node) const {
16761762
DAG.getNode(ISD::XOR, DL, IntVT, SignAsInt.IntValue, SignMask);
16771763

16781764
// Convert back to float.
1679-
return DAG.modifySignAsInt(SignAsInt, DL, SignFlip);
1765+
return modifySignAsInt(SignAsInt, DL, SignFlip);
16801766
}
16811767

16821768
SDValue SelectionDAGLegalize::ExpandFABS(SDNode *Node) const {
@@ -1692,12 +1778,12 @@ SDValue SelectionDAGLegalize::ExpandFABS(SDNode *Node) const {
16921778

16931779
// Transform value to integer, clear the sign bit and transform back.
16941780
FloatSignAsInt ValueAsInt;
1695-
DAG.getSignAsIntValue(ValueAsInt, DL, Value);
1781+
getSignAsIntValue(ValueAsInt, DL, Value);
16961782
EVT IntVT = ValueAsInt.IntValue.getValueType();
16971783
SDValue ClearSignMask = DAG.getConstant(~ValueAsInt.SignMask, DL, IntVT);
16981784
SDValue ClearedSign = DAG.getNode(ISD::AND, DL, IntVT, ValueAsInt.IntValue,
16991785
ClearSignMask);
1700-
return DAG.modifySignAsInt(ValueAsInt, DL, ClearedSign);
1786+
return modifySignAsInt(ValueAsInt, DL, ClearedSign);
17011787
}
17021788

17031789
void SelectionDAGLegalize::ExpandDYNAMIC_STACKALLOC(SDNode* Node,

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2760,66 +2760,6 @@ SDValue SelectionDAG::CreateStackTemporary(EVT VT1, EVT VT2) {
27602760
return CreateStackTemporary(Bytes, Align);
27612761
}
27622762

2763-
void SelectionDAG::getSignAsIntValue(FloatSignAsInt &State, const SDLoc &DL,
2764-
SDValue Value) {
2765-
EVT FloatVT = Value.getValueType();
2766-
unsigned NumBits = FloatVT.getScalarSizeInBits();
2767-
State.FloatVT = FloatVT;
2768-
EVT IVT = FloatVT.changeTypeToInteger();
2769-
// Convert to an integer of the same size.
2770-
if (TLI->isTypeLegal(IVT)) {
2771-
State.IntValue = getNode(ISD::BITCAST, DL, IVT, Value);
2772-
State.SignMask = APInt::getSignMask(NumBits);
2773-
State.SignBit = NumBits - 1;
2774-
return;
2775-
}
2776-
2777-
auto &DataLayout = getDataLayout();
2778-
// Store the float to memory, then load the sign part out as an integer.
2779-
MVT LoadTy = TLI->getRegisterType(MVT::i8);
2780-
// First create a temporary that is aligned for both the load and store.
2781-
SDValue StackPtr = CreateStackTemporary(FloatVT, LoadTy);
2782-
int FI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
2783-
// Then store the float to it.
2784-
State.FloatPtr = StackPtr;
2785-
MachineFunction &MF = getMachineFunction();
2786-
State.FloatPointerInfo = MachinePointerInfo::getFixedStack(MF, FI);
2787-
State.Chain = getStore(getEntryNode(), DL, Value, State.FloatPtr,
2788-
State.FloatPointerInfo);
2789-
2790-
SDValue IntPtr;
2791-
if (DataLayout.isBigEndian()) {
2792-
assert(FloatVT.isByteSized() && "Unsupported floating point type!");
2793-
// Load out a legal integer with the same sign bit as the float.
2794-
IntPtr = StackPtr;
2795-
State.IntPointerInfo = State.FloatPointerInfo;
2796-
} else {
2797-
// Advance the pointer so that the loaded byte will contain the sign bit.
2798-
unsigned ByteOffset = (NumBits / 8) - 1;
2799-
IntPtr = getMemBasePlusOffset(StackPtr, TypeSize::getFixed(ByteOffset), DL);
2800-
State.IntPointerInfo =
2801-
MachinePointerInfo::getFixedStack(MF, FI, ByteOffset);
2802-
}
2803-
2804-
State.IntPtr = IntPtr;
2805-
State.IntValue = getExtLoad(ISD::EXTLOAD, DL, LoadTy, State.Chain, IntPtr,
2806-
State.IntPointerInfo, MVT::i8);
2807-
State.SignMask = APInt::getOneBitSet(LoadTy.getScalarSizeInBits(), 7);
2808-
State.SignBit = 7;
2809-
}
2810-
2811-
SDValue SelectionDAG::modifySignAsInt(const FloatSignAsInt &State,
2812-
const SDLoc &DL, SDValue NewIntValue) {
2813-
if (!State.Chain)
2814-
return getNode(ISD::BITCAST, DL, State.FloatVT, NewIntValue);
2815-
2816-
// Override the part containing the sign bit in the value stored on the stack.
2817-
SDValue Chain = getTruncStore(State.Chain, DL, NewIntValue, State.IntPtr,
2818-
State.IntPointerInfo, MVT::i8);
2819-
return getLoad(State.FloatVT, DL, Chain, State.FloatPtr,
2820-
State.FloatPointerInfo);
2821-
}
2822-
28232763
SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
28242764
ISD::CondCode Cond, const SDLoc &dl) {
28252765
EVT OpVT = N1.getValueType();

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8610,18 +8610,16 @@ SDValue TargetLowering::expandFMINIMUM_FMAXIMUM(SDNode *N,
86108610
// fminimum/fmaximum requires -0.0 less than +0.0
86118611
if (!MinMaxMustRespectOrderedZero && !N->getFlags().hasNoSignedZeros() &&
86128612
!DAG.isKnownNeverZeroFloat(RHS) && !DAG.isKnownNeverZeroFloat(LHS)) {
8613-
auto IsSpecificZero = [&](SDValue F) {
8614-
FloatSignAsInt State;
8615-
DAG.getSignAsIntValue(State, DL, F);
8616-
return DAG.getSetCC(DL, CCVT, State.IntValue,
8617-
DAG.getConstant(0, DL, State.IntValue.getValueType()),
8618-
IsMax ? ISD::SETEQ : ISD::SETNE);
8619-
};
86208613
SDValue IsZero = DAG.getSetCC(DL, CCVT, MinMax,
86218614
DAG.getConstantFP(0.0, DL, VT), ISD::SETOEQ);
8622-
SDValue LCmp =
8623-
DAG.getSelect(DL, VT, IsSpecificZero(LHS), LHS, MinMax, Flags);
8624-
SDValue RCmp = DAG.getSelect(DL, VT, IsSpecificZero(RHS), RHS, LCmp, Flags);
8615+
SDValue TestZero =
8616+
DAG.getTargetConstant(IsMax ? fcPosZero : fcNegZero, DL, MVT::i32);
8617+
SDValue LCmp = DAG.getSelect(
8618+
DL, VT, DAG.getNode(ISD::IS_FPCLASS, DL, CCVT, LHS, TestZero), LHS,
8619+
MinMax, Flags);
8620+
SDValue RCmp = DAG.getSelect(
8621+
DL, VT, DAG.getNode(ISD::IS_FPCLASS, DL, CCVT, RHS, TestZero), RHS,
8622+
LCmp, Flags);
86258623
MinMax = DAG.getSelect(DL, VT, IsZero, RCmp, MinMax, Flags);
86268624
}
86278625

llvm/test/CodeGen/AArch64/fmaximum-legalization.ll

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -41,59 +41,3 @@ define <4 x half> @fmaximum_v4f16(<4 x half> %x, <4 x half> %y) {
4141
%r = call <4 x half> @llvm.maximum.v4f16(<4 x half> %x, <4 x half> %y)
4242
ret <4 x half> %r
4343
}
44-
45-
define fp128 @maximum_fp128(fp128 %x, fp128 %y) nounwind {
46-
; CHECK-LABEL: maximum_fp128:
47-
; CHECK: // %bb.0:
48-
; CHECK-NEXT: sub sp, sp, #96
49-
; CHECK-NEXT: str x30, [sp, #80] // 8-byte Folded Spill
50-
; CHECK-NEXT: stp q0, q1, [sp] // 32-byte Folded Spill
51-
; CHECK-NEXT: stp q1, q0, [sp, #48]
52-
; CHECK-NEXT: bl __gttf2
53-
; CHECK-NEXT: ldp q0, q1, [sp] // 32-byte Folded Reload
54-
; CHECK-NEXT: cmp w0, #0
55-
; CHECK-NEXT: b.le .LBB1_2
56-
; CHECK-NEXT: // %bb.1:
57-
; CHECK-NEXT: mov v1.16b, v0.16b
58-
; CHECK-NEXT: .LBB1_2:
59-
; CHECK-NEXT: str q1, [sp, #32] // 16-byte Folded Spill
60-
; CHECK-NEXT: ldr q1, [sp, #16] // 16-byte Folded Reload
61-
; CHECK-NEXT: bl __unordtf2
62-
; CHECK-NEXT: ldr q0, [sp, #32] // 16-byte Folded Reload
63-
; CHECK-NEXT: cmp w0, #0
64-
; CHECK-NEXT: b.eq .LBB1_4
65-
; CHECK-NEXT: // %bb.3:
66-
; CHECK-NEXT: adrp x8, .LCPI1_0
67-
; CHECK-NEXT: ldr q0, [x8, :lo12:.LCPI1_0]
68-
; CHECK-NEXT: .LBB1_4:
69-
; CHECK-NEXT: ldrb w8, [sp, #79]
70-
; CHECK-NEXT: mov v1.16b, v0.16b
71-
; CHECK-NEXT: cmp w8, #0
72-
; CHECK-NEXT: b.ne .LBB1_6
73-
; CHECK-NEXT: // %bb.5:
74-
; CHECK-NEXT: ldr q1, [sp] // 16-byte Folded Reload
75-
; CHECK-NEXT: .LBB1_6:
76-
; CHECK-NEXT: ldrb w8, [sp, #63]
77-
; CHECK-NEXT: cmp w8, #0
78-
; CHECK-NEXT: b.ne .LBB1_8
79-
; CHECK-NEXT: // %bb.7:
80-
; CHECK-NEXT: ldr q1, [sp, #16] // 16-byte Folded Reload
81-
; CHECK-NEXT: .LBB1_8:
82-
; CHECK-NEXT: adrp x8, .LCPI1_1
83-
; CHECK-NEXT: str q0, [sp, #32] // 16-byte Folded Spill
84-
; CHECK-NEXT: str q1, [sp, #16] // 16-byte Folded Spill
85-
; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI1_1]
86-
; CHECK-NEXT: ldr q0, [sp, #32] // 16-byte Folded Reload
87-
; CHECK-NEXT: bl __eqtf2
88-
; CHECK-NEXT: ldr q0, [sp, #32] // 16-byte Folded Reload
89-
; CHECK-NEXT: cmp w0, #0
90-
; CHECK-NEXT: b.ne .LBB1_10
91-
; CHECK-NEXT: // %bb.9:
92-
; CHECK-NEXT: ldr q0, [sp, #16] // 16-byte Folded Reload
93-
; CHECK-NEXT: .LBB1_10:
94-
; CHECK-NEXT: ldr x30, [sp, #80] // 8-byte Folded Reload
95-
; CHECK-NEXT: add sp, sp, #96
96-
; CHECK-NEXT: ret
97-
%res = call fp128 @llvm.maximum.f128(fp128 %x, fp128 %y)
98-
ret fp128 %res
99-
}

0 commit comments

Comments
 (0)