From 7f54b38e28b3b66195de672848f2b5366d0d51e3 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 9 May 2023 09:52:44 +0100 Subject: [PATCH] GlobalISel: Refactor unary FP op constant folding --- .../llvm/CodeGen/GlobalISel/CombinerHelper.h | 6 +- .../llvm/CodeGen/GlobalISel/MachineIRBuilder.h | 4 ++ llvm/include/llvm/Target/GlobalISel/Combine.td | 2 +- llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp | 75 ++++++++++++---------- 4 files changed, 48 insertions(+), 39 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h index ec37620..c22355a 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h @@ -29,6 +29,7 @@ namespace llvm { class GISelChangeObserver; class APFloat; class APInt; +class ConstantFP; class GPtrAdd; class GStore; class GZExtLoad; @@ -353,9 +354,8 @@ public: /// Transform fp_instr(cst) to constant result of the fp operation. bool matchCombineConstantFoldFpUnary(MachineInstr &MI, - std::optional &Cst); - void applyCombineConstantFoldFpUnary(MachineInstr &MI, - std::optional &Cst); + const ConstantFP *&Cst); + void applyCombineConstantFoldFpUnary(MachineInstr &MI, const ConstantFP *Cst); /// Transform IntToPtr(PtrToInt(x)) to x if cast is in the same address space. bool matchCombineI2PToP2I(MachineInstr &MI, Register &Reg); diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index a4168d9..071fbe8 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -284,6 +284,10 @@ public: return getMF().getFunction().getParent()->getDataLayout(); } + LLVMContext &getContext() const { + return getMF().getFunction().getContext(); + } + /// Getter for DebugLoc const DebugLoc &getDL() { return State.DL; } diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td index 40ccfb0..f4f8d6b 100644 --- a/llvm/include/llvm/Target/GlobalISel/Combine.td +++ b/llvm/include/llvm/Target/GlobalISel/Combine.td @@ -469,7 +469,7 @@ def simplify_add_to_sub: GICombineRule < >; // Fold fp_op(cst) to the constant result of the floating point operation. -def constant_fp_op_matchinfo: GIDefMatchData<"std::optional">; +def constant_fp_op_matchinfo: GIDefMatchData<"const ConstantFP *">; def constant_fp_op: GICombineRule < (defs root:$root, constant_fp_op_matchinfo:$info), (match (wip_match_opcode G_FNEG, G_FABS, G_FPTRUNC, G_FSQRT, G_FLOG2):$root, diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index 05d473e..0bbfdd4 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -1289,64 +1289,69 @@ bool CombinerHelper::tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen) { } static std::optional -constantFoldFpUnary(unsigned Opcode, LLT DstTy, const Register Op, - const MachineRegisterInfo &MRI) { - const ConstantFP *MaybeCst = getConstantFPVRegVal(Op, MRI); - if (!MaybeCst) - return std::nullopt; - - APFloat V = MaybeCst->getValueAPF(); - switch (Opcode) { +constantFoldFpUnary(const MachineInstr &MI, const MachineRegisterInfo &MRI, + const APFloat &Val) { + APFloat Result(Val); + switch (MI.getOpcode()) { default: llvm_unreachable("Unexpected opcode!"); case TargetOpcode::G_FNEG: { - V.changeSign(); - return V; + Result.changeSign(); + return Result; } case TargetOpcode::G_FABS: { - V.clearSign(); - return V; + Result.clearSign(); + return Result; + } + case TargetOpcode::G_FPTRUNC: { + bool Unused; + LLT DstTy = MRI.getType(MI.getOperand(0).getReg()); + Result.convert(getFltSemanticForLLT(DstTy), APFloat::rmNearestTiesToEven, + &Unused); + return Result; } - case TargetOpcode::G_FPTRUNC: - break; case TargetOpcode::G_FSQRT: { bool Unused; - V.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &Unused); - V = APFloat(sqrt(V.convertToDouble())); + Result.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, + &Unused); + Result = APFloat(sqrt(Result.convertToDouble())); break; } case TargetOpcode::G_FLOG2: { bool Unused; - V.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &Unused); - V = APFloat(log2(V.convertToDouble())); + Result.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, + &Unused); + Result = APFloat(log2(Result.convertToDouble())); break; } } // Convert `APFloat` to appropriate IEEE type depending on `DstTy`. Otherwise, - // `buildFConstant` will assert on size mismatch. Only `G_FPTRUNC`, `G_FSQRT`, - // and `G_FLOG2` reach here. + // `buildFConstant` will assert on size mismatch. Only `G_FSQRT`, and + // `G_FLOG2` reach here. bool Unused; - V.convert(getFltSemanticForLLT(DstTy), APFloat::rmNearestTiesToEven, &Unused); - return V; + Result.convert(Val.getSemantics(), APFloat::rmNearestTiesToEven, &Unused); + return Result; } -bool CombinerHelper::matchCombineConstantFoldFpUnary( - MachineInstr &MI, std::optional &Cst) { - Register DstReg = MI.getOperand(0).getReg(); +bool CombinerHelper::matchCombineConstantFoldFpUnary(MachineInstr &MI, + const ConstantFP *&Cst) { Register SrcReg = MI.getOperand(1).getReg(); - LLT DstTy = MRI.getType(DstReg); - Cst = constantFoldFpUnary(MI.getOpcode(), DstTy, SrcReg, MRI); - return Cst.has_value(); + const ConstantFP *MaybeCst = getConstantFPVRegVal(SrcReg, MRI); + if (!MaybeCst) + return false; + + if (auto Folded = constantFoldFpUnary(MI, MRI, MaybeCst->getValue())) { + Cst = ConstantFP::get(Builder.getContext(), *Folded); + return true; + } + + return false; } -void CombinerHelper::applyCombineConstantFoldFpUnary( - MachineInstr &MI, std::optional &Cst) { - assert(Cst && "Optional is unexpectedly empty!"); +void CombinerHelper::applyCombineConstantFoldFpUnary(MachineInstr &MI, + const ConstantFP *Cst) { Builder.setInstrAndDebugLoc(MI); - MachineFunction &MF = Builder.getMF(); - auto *FPVal = ConstantFP::get(MF.getFunction().getContext(), *Cst); - Register DstReg = MI.getOperand(0).getReg(); - Builder.buildFConstant(DstReg, *FPVal); + Builder.buildFConstant(MI.getOperand(0), *Cst); MI.eraseFromParent(); } -- 2.7.4