diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2024-05-29 12:26:27 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-29 12:26:27 +0200 |
commit | aef0bdd36d888edd1575713e4976162daf81ff5b (patch) | |
tree | f5302069c33bd68bee222986c54037bc5080dfc6 | |
parent | 6543453c3604c5532666a9bad2bf3d261099dab5 (diff) | |
download | llvm-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.h | 4 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 15 |
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; |