aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2024-05-29 12:26:27 +0200
committerGitHub <noreply@github.com>2024-05-29 12:26:27 +0200
commitaef0bdd36d888edd1575713e4976162daf81ff5b (patch)
treef5302069c33bd68bee222986c54037bc5080dfc6
parent6543453c3604c5532666a9bad2bf3d261099dab5 (diff)
downloadllvm-aef0bdd36d888edd1575713e4976162daf81ff5b.zip
llvm-aef0bdd36d888edd1575713e4976162daf81ff5b.tar.gz
llvm-aef0bdd36d888edd1575713e4976162daf81ff5b.tar.bz2
DAG: Preserve flags when expanding fminimum/fmaximum (#93550)
The operation selection logic here doesn't really work when vector types need to be split. This was also dropping the flags, and losing nnan made the combine from select back to fmin/fmax unrecoverable. Preserve the flags to assist a future commit.
-rw-r--r--llvm/include/llvm/CodeGen/SelectionDAG.h4
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp15
2 files changed, 10 insertions, 9 deletions
diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index 96a6270..0dc2373 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -1241,11 +1241,11 @@ public:
/// Helper function to make it easier to build Select's if you just have
/// operands and don't want to check for vector.
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS,
- SDValue RHS) {
+ SDValue RHS, SDNodeFlags Flags = SDNodeFlags()) {
assert(LHS.getValueType() == VT && RHS.getValueType() == VT &&
"Cannot use select on differing types");
auto Opcode = Cond.getValueType().isVector() ? ISD::VSELECT : ISD::SELECT;
- return getNode(Opcode, DL, VT, Cond, LHS, RHS);
+ return getNode(Opcode, DL, VT, Cond, LHS, RHS, Flags);
}
/// Helper function to make it easier to build SelectCC's if you just have an
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 4e47f50..623b634 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -8428,6 +8428,7 @@ SDValue TargetLowering::expandFMINIMUM_FMAXIMUM(SDNode *N,
EVT VT = N->getValueType(0);
EVT CCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
bool IsMax = Opc == ISD::FMAXIMUM;
+ SDNodeFlags Flags = N->getFlags();
if (VT.isVector() &&
isOperationLegalOrCustomOrPromote(Opc, VT.getScalarType()))
@@ -8444,15 +8445,15 @@ SDValue TargetLowering::expandFMINIMUM_FMAXIMUM(SDNode *N,
bool MinMaxMustRespectOrderedZero = false;
if (isOperationLegalOrCustom(CompOpcIeee, VT)) {
- MinMax = DAG.getNode(CompOpcIeee, DL, VT, LHS, RHS);
+ MinMax = DAG.getNode(CompOpcIeee, DL, VT, LHS, RHS, Flags);
MinMaxMustRespectOrderedZero = true;
} else if (isOperationLegalOrCustom(CompOpc, VT)) {
- MinMax = DAG.getNode(CompOpc, DL, VT, LHS, RHS);
+ MinMax = DAG.getNode(CompOpc, DL, VT, LHS, RHS, Flags);
} else {
// NaN (if exists) will be propagated later, so orderness doesn't matter.
SDValue Compare =
DAG.getSetCC(DL, CCVT, LHS, RHS, IsMax ? ISD::SETGT : ISD::SETLT);
- MinMax = DAG.getSelect(DL, VT, Compare, LHS, RHS);
+ MinMax = DAG.getSelect(DL, VT, Compare, LHS, RHS, Flags);
}
// Propagate any NaN of both operands
@@ -8461,7 +8462,7 @@ SDValue TargetLowering::expandFMINIMUM_FMAXIMUM(SDNode *N,
ConstantFP *FPNaN = ConstantFP::get(
*DAG.getContext(), APFloat::getNaN(DAG.EVTToAPFloatSemantics(VT)));
MinMax = DAG.getSelect(DL, VT, DAG.getSetCC(DL, CCVT, LHS, RHS, ISD::SETUO),
- DAG.getConstantFP(*FPNaN, DL, VT), MinMax);
+ DAG.getConstantFP(*FPNaN, DL, VT), MinMax, Flags);
}
// fminimum/fmaximum requires -0.0 less than +0.0
@@ -8473,11 +8474,11 @@ SDValue TargetLowering::expandFMINIMUM_FMAXIMUM(SDNode *N,
DAG.getTargetConstant(IsMax ? fcPosZero : fcNegZero, DL, MVT::i32);
SDValue LCmp = DAG.getSelect(
DL, VT, DAG.getNode(ISD::IS_FPCLASS, DL, CCVT, LHS, TestZero), LHS,
- MinMax);
+ MinMax, Flags);
SDValue RCmp = DAG.getSelect(
DL, VT, DAG.getNode(ISD::IS_FPCLASS, DL, CCVT, RHS, TestZero), RHS,
- LCmp);
- MinMax = DAG.getSelect(DL, VT, IsZero, RCmp, MinMax);
+ LCmp, Flags);
+ MinMax = DAG.getSelect(DL, VT, IsZero, RCmp, MinMax, Flags);
}
return MinMax;