mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
[SelectionDAG] Make sure FMF are propagated when getSetcc canonicalizes FP constants to RHS.
getNode handling for ISD:SETCC calls FoldSETCC which can canonicalize FP constants to the RHS. When this happens we should create the node with the FMF that was requested. By using FlagInserter when can ensure any calls to getNode/getSetcc during canonicalization will also get the flags. Differential Revision: https://reviews.llvm.org/D88063
This commit is contained in:
parent
d5e99701a1
commit
2ef989f13e
@ -339,11 +339,13 @@ public:
|
||||
FlagInserter *LastInserter;
|
||||
|
||||
public:
|
||||
FlagInserter(SelectionDAG &SDAG, SDNode *N)
|
||||
: DAG(SDAG), Flags(N->getFlags()),
|
||||
FlagInserter(SelectionDAG &SDAG, SDNodeFlags Flags)
|
||||
: DAG(SDAG), Flags(Flags),
|
||||
LastInserter(SDAG.getFlagInserter()) {
|
||||
SDAG.setFlagInserter(this);
|
||||
}
|
||||
FlagInserter(SelectionDAG &SDAG, SDNode *N)
|
||||
: FlagInserter(SDAG, N->getFlags()) {}
|
||||
|
||||
FlagInserter(const FlagInserter &) = delete;
|
||||
FlagInserter &operator=(const FlagInserter &) = delete;
|
||||
@ -1083,8 +1085,8 @@ public:
|
||||
/// Helper function to make it easier to build SetCC's if you just have an
|
||||
/// ISD::CondCode instead of an SDValue.
|
||||
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS,
|
||||
ISD::CondCode Cond, SDNodeFlags Flags = SDNodeFlags(),
|
||||
SDValue Chain = SDValue(), bool IsSignaling = false) {
|
||||
ISD::CondCode Cond, SDValue Chain = SDValue(),
|
||||
bool IsSignaling = false) {
|
||||
assert(LHS.getValueType().isVector() == RHS.getValueType().isVector() &&
|
||||
"Cannot compare scalars to vectors");
|
||||
assert(LHS.getValueType().isVector() == VT.isVector() &&
|
||||
@ -1094,7 +1096,7 @@ public:
|
||||
if (Chain)
|
||||
return getNode(IsSignaling ? ISD::STRICT_FSETCCS : ISD::STRICT_FSETCC, DL,
|
||||
{VT, MVT::Other}, {Chain, LHS, RHS, getCondCode(Cond)});
|
||||
return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond), Flags);
|
||||
return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond));
|
||||
}
|
||||
|
||||
/// Helper function to make it easier to build Select's if you just have
|
||||
|
@ -7437,7 +7437,7 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
|
||||
// FIXME Can we handle multiple uses? Could we token factor the chain
|
||||
// results from the new/old setcc?
|
||||
SDValue SetCC =
|
||||
DAG.getSetCC(SDLoc(N0), VT, LHS, RHS, NotCC, SDNodeFlags(),
|
||||
DAG.getSetCC(SDLoc(N0), VT, LHS, RHS, NotCC,
|
||||
N0.getOperand(0), N0Opcode == ISD::STRICT_FSETCCS);
|
||||
CombineTo(N, SetCC);
|
||||
DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), SetCC.getValue(1));
|
||||
|
@ -1754,15 +1754,15 @@ bool SelectionDAGLegalize::LegalizeSetCCCondCode(
|
||||
if (CCCode != ISD::SETO && CCCode != ISD::SETUO) {
|
||||
// If we aren't the ordered or unorder operation,
|
||||
// then the pattern is (LHS CC1 RHS) Opc (LHS CC2 RHS).
|
||||
SetCC1 = DAG.getSetCC(dl, VT, LHS, RHS, CC1, SDNodeFlags(), Chain,
|
||||
SetCC1 = DAG.getSetCC(dl, VT, LHS, RHS, CC1, Chain,
|
||||
IsSignaling);
|
||||
SetCC2 = DAG.getSetCC(dl, VT, LHS, RHS, CC2, SDNodeFlags(), Chain,
|
||||
SetCC2 = DAG.getSetCC(dl, VT, LHS, RHS, CC2, Chain,
|
||||
IsSignaling);
|
||||
} else {
|
||||
// Otherwise, the pattern is (LHS CC1 LHS) Opc (RHS CC2 RHS)
|
||||
SetCC1 = DAG.getSetCC(dl, VT, LHS, LHS, CC1, SDNodeFlags(), Chain,
|
||||
SetCC1 = DAG.getSetCC(dl, VT, LHS, LHS, CC1, Chain,
|
||||
IsSignaling);
|
||||
SetCC2 = DAG.getSetCC(dl, VT, RHS, RHS, CC2, SDNodeFlags(), Chain,
|
||||
SetCC2 = DAG.getSetCC(dl, VT, RHS, RHS, CC2, Chain,
|
||||
IsSignaling);
|
||||
}
|
||||
if (Chain)
|
||||
|
@ -1793,18 +1793,18 @@ void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS,
|
||||
// The following can be improved, but not that much.
|
||||
SDValue Tmp1, Tmp2, Tmp3, OutputChain;
|
||||
Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi,
|
||||
RHSHi, ISD::SETOEQ, SDNodeFlags(), Chain, IsSignaling);
|
||||
RHSHi, ISD::SETOEQ, Chain, IsSignaling);
|
||||
OutputChain = Tmp1->getNumValues() > 1 ? Tmp1.getValue(1) : SDValue();
|
||||
Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.getValueType()), LHSLo,
|
||||
RHSLo, CCCode, SDNodeFlags(), OutputChain, IsSignaling);
|
||||
RHSLo, CCCode, OutputChain, IsSignaling);
|
||||
OutputChain = Tmp2->getNumValues() > 1 ? Tmp2.getValue(1) : SDValue();
|
||||
Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
|
||||
Tmp1 =
|
||||
DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi,
|
||||
ISD::SETUNE, SDNodeFlags(), OutputChain, IsSignaling);
|
||||
ISD::SETUNE, OutputChain, IsSignaling);
|
||||
OutputChain = Tmp1->getNumValues() > 1 ? Tmp1.getValue(1) : SDValue();
|
||||
Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi,
|
||||
RHSHi, CCCode, SDNodeFlags(), OutputChain, IsSignaling);
|
||||
RHSHi, CCCode, OutputChain, IsSignaling);
|
||||
OutputChain = Tmp2->getNumValues() > 1 ? Tmp2.getValue(1) : SDValue();
|
||||
Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
|
||||
NewLHS = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3);
|
||||
|
@ -3097,10 +3097,11 @@ void SelectionDAGBuilder::visitFCmp(const User &I) {
|
||||
|
||||
SDNodeFlags Flags;
|
||||
Flags.copyFMF(*FPMO);
|
||||
SelectionDAG::FlagInserter FlagsInserter(DAG, Flags);
|
||||
|
||||
EVT DestVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
|
||||
I.getType());
|
||||
setValue(&I, DAG.getSetCC(getCurSDLoc(), DestVT, Op1, Op2, Condition, Flags));
|
||||
setValue(&I, DAG.getSetCC(getCurSDLoc(), DestVT, Op1, Op2, Condition));
|
||||
}
|
||||
|
||||
// Check if the condition of the select has one use or two users that are both
|
||||
|
@ -6426,7 +6426,7 @@ bool TargetLowering::expandFP_TO_UINT(SDNode *Node, SDValue &Result,
|
||||
SDValue Sel;
|
||||
|
||||
if (Node->isStrictFPOpcode()) {
|
||||
Sel = DAG.getSetCC(dl, SetCCVT, Src, Cst, ISD::SETLT, SDNodeFlags(),
|
||||
Sel = DAG.getSetCC(dl, SetCCVT, Src, Cst, ISD::SETLT,
|
||||
Node->getOperand(0), /*IsSignaling*/ true);
|
||||
Chain = Sel.getValue(1);
|
||||
} else {
|
||||
|
@ -8287,7 +8287,7 @@ SDValue PPCTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
|
||||
EVT DstSetCCVT =
|
||||
getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), DstVT);
|
||||
SDValue Sel = DAG.getSetCC(dl, SetCCVT, Src, Cst, ISD::SETLT,
|
||||
SDNodeFlags(), Chain, true);
|
||||
Chain, true);
|
||||
Chain = Sel.getValue(1);
|
||||
|
||||
SDValue FltOfs = DAG.getSelect(
|
||||
|
@ -20457,7 +20457,7 @@ X86TargetLowering::FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG,
|
||||
*DAG.getContext(), TheVT);
|
||||
SDValue Cmp;
|
||||
if (IsStrict) {
|
||||
Cmp = DAG.getSetCC(DL, ResVT, Value, ThreshVal, ISD::SETLT, SDNodeFlags(),
|
||||
Cmp = DAG.getSetCC(DL, ResVT, Value, ThreshVal, ISD::SETLT,
|
||||
Chain, /*IsSignaling*/ true);
|
||||
Chain = Cmp.getValue(1);
|
||||
} else {
|
||||
|
@ -28,7 +28,7 @@ define float @fmf_transfer(float %x, float %y) {
|
||||
ret float %f8
|
||||
}
|
||||
|
||||
; CHECK: Optimized type-legalized selection DAG: %bb.0 'fmf_setcc:'
|
||||
; CHECK-LABEL: Optimized type-legalized selection DAG: %bb.0 'fmf_setcc:'
|
||||
; CHECK: t13: i8 = setcc nnan ninf nsz arcp contract afn reassoc t2, ConstantFP:f32<0.000000e+00>, setlt:ch
|
||||
|
||||
define float @fmf_setcc(float %x, float %y) {
|
||||
@ -36,3 +36,11 @@ define float @fmf_setcc(float %x, float %y) {
|
||||
%ret = select i1 %cmp, float %x, float %y
|
||||
ret float %ret
|
||||
}
|
||||
|
||||
; CHECK-LABEL: Initial selection DAG: %bb.0 'fmf_setcc_canon:'
|
||||
; CHECK: t14: i8 = setcc nnan ninf nsz arcp contract afn reassoc t2, ConstantFP:f32<0.000000e+00>, setgt:ch
|
||||
define float @fmf_setcc_canon(float %x, float %y) {
|
||||
%cmp = fcmp fast ult float 0.0, %x
|
||||
%ret = select i1 %cmp, float %x, float %y
|
||||
ret float %ret
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user