|
13 | 13 | //===----------------------------------------------------------------------===//
|
14 | 14 |
|
15 | 15 | #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
|
| 16 | +#include "llvm/ADT/APFloat.h" |
16 | 17 | #include "llvm/CodeGen/GlobalISel/CallLowering.h"
|
17 | 18 | #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
|
18 | 19 | #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
|
|
32 | 33 | #include "llvm/CodeGen/TargetLowering.h"
|
33 | 34 | #include "llvm/CodeGen/TargetOpcodes.h"
|
34 | 35 | #include "llvm/CodeGen/TargetSubtargetInfo.h"
|
| 36 | +#include "llvm/IR/InstrTypes.h" |
35 | 37 | #include "llvm/IR/Instructions.h"
|
36 | 38 | #include "llvm/Support/Debug.h"
|
37 | 39 | #include "llvm/Support/MathExtras.h"
|
@@ -4594,6 +4596,9 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
|
4594 | 4596 | case G_FMINNUM:
|
4595 | 4597 | case G_FMAXNUM:
|
4596 | 4598 | return lowerFMinNumMaxNum(MI);
|
| 4599 | + case G_FMINIMUM: |
| 4600 | + case G_FMAXIMUM: |
| 4601 | + return lowerFMinimum_FMaximum(MI); |
4597 | 4602 | case G_MERGE_VALUES:
|
4598 | 4603 | return lowerMergeValues(MI);
|
4599 | 4604 | case G_UNMERGE_VALUES:
|
@@ -8165,6 +8170,62 @@ LegalizerHelper::lowerFMinNumMaxNum(MachineInstr &MI) {
|
8165 | 8170 | return Legalized;
|
8166 | 8171 | }
|
8167 | 8172 |
|
| 8173 | +LegalizerHelper::LegalizeResult |
| 8174 | +LegalizerHelper::lowerFMinimum_FMaximum(MachineInstr &MI) { |
| 8175 | + auto [Dst, Src0, Src1] = MI.getFirst3Regs(); |
| 8176 | + LLT Ty = MRI.getType(Dst); |
| 8177 | + unsigned Opc = MI.getOpcode(); |
| 8178 | + bool IsMax = Opc == TargetOpcode::G_FMAXIMUM; |
| 8179 | + |
| 8180 | + Register MinMax; |
| 8181 | + unsigned CompOpcIeee = IsMax ? TargetOpcode::G_FMAXNUM_IEEE : TargetOpcode::G_FMINNUM_IEEE; |
| 8182 | + unsigned CompOpc = IsMax ? TargetOpcode::G_FMAXNUM : TargetOpcode::G_FMINNUM; |
| 8183 | + CmpInst::Predicate CompPred = IsMax ? CmpInst::FCMP_OGT : CmpInst::FCMP_OLT; |
| 8184 | + LLT S1 = LLT::scalar(1); |
| 8185 | + const fltSemantics &FPSem = getFltSemanticForLLT(Ty); |
| 8186 | + |
| 8187 | + bool MinMaxMustRespectOrderedZero = false; |
| 8188 | + |
| 8189 | + if (LI.isLegalOrCustom({CompOpcIeee, Ty})) { |
| 8190 | + MinMax = MIRBuilder.buildInstr(CompOpcIeee, {Ty}, {Src0, Src1}).getReg(0); |
| 8191 | + MinMaxMustRespectOrderedZero = true; |
| 8192 | + } else if (LI.isLegalOrCustom({CompOpc, Ty})) { |
| 8193 | + MinMax = MIRBuilder.buildInstr(CompOpc, {Ty}, {Src0, Src1}).getReg(0); |
| 8194 | + } else { |
| 8195 | + // NaN (if exists) will be propagated later, so orderness doesn't matter. |
| 8196 | + auto Comp = MIRBuilder.buildFCmp(CompPred, S1, Src0, Src1); |
| 8197 | + MinMax = MIRBuilder.buildSelect(Ty, Comp,Src0, Src1).getReg(0); |
| 8198 | + } |
| 8199 | + |
| 8200 | + // Propagate any NaN of both operands |
| 8201 | + if (!MI.getFlag(MachineInstr::FmNoNans) && (!isKnownNeverNaN(Src0, MRI) || !isKnownNeverNaN(Src1, MRI))) { |
| 8202 | + auto FPNaN = MIRBuilder.buildFConstant(Ty, APFloat::getNaN(FPSem)); |
| 8203 | + auto Comp = MIRBuilder.buildFCmp(CmpInst::Predicate::FCMP_UNO, S1, Src0, Src1); |
| 8204 | + MinMax = MIRBuilder.buildSelect(Ty, Comp, FPNaN, MinMax).getReg(0); |
| 8205 | + } |
| 8206 | + |
| 8207 | + // fminimum/fmaximum requires -0.0 less than +0.0 |
| 8208 | + if (!MinMaxMustRespectOrderedZero && !MI.getFlag(MachineInstr::FmNsz) && |
| 8209 | + !isKnownNeverZeroFloat(Src0, MRI) && !isKnownNeverZeroFloat(Src1, MRI)) { |
| 8210 | + auto Zero = MIRBuilder.buildFConstant(Ty, APFloat::getZero(FPSem)); |
| 8211 | + auto IsZero = MIRBuilder.buildFCmp(CmpInst::Predicate::FCMP_OEQ, S1,MinMax, Zero); |
| 8212 | + |
| 8213 | + unsigned TestZeroMask = IsMax ? fcPosZero : fcNegZero; |
| 8214 | + |
| 8215 | + auto Src0Zero = MIRBuilder.buildIsFPClass(S1, Src0, TestZeroMask); |
| 8216 | + auto Src0Comp = MIRBuilder.buildSelect(Ty, Src0Zero, Src0, MinMax); |
| 8217 | + |
| 8218 | + auto Src1Zero = MIRBuilder.buildIsFPClass(S1, Src1, TestZeroMask); |
| 8219 | + auto Src1Comp = MIRBuilder.buildSelect(Ty, Src1Zero, Src1, Src0Comp); |
| 8220 | + |
| 8221 | + MinMax = MIRBuilder.buildSelect(Ty, IsZero, Src1Comp, MinMax).getReg(0); |
| 8222 | + } |
| 8223 | + |
| 8224 | + MRI.replaceRegWith(Dst, MinMax); |
| 8225 | + MI.eraseFromParent(); |
| 8226 | + return Legalized; |
| 8227 | +} |
| 8228 | + |
8168 | 8229 | LegalizerHelper::LegalizeResult LegalizerHelper::lowerFMad(MachineInstr &MI) {
|
8169 | 8230 | // Expand G_FMAD a, b, c -> G_FADD (G_FMUL a, b), c
|
8170 | 8231 | Register DstReg = MI.getOperand(0).getReg();
|
|
0 commit comments