Index: llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h =================================================================== --- llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h +++ llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h @@ -29,6 +29,7 @@ class GISelChangeObserver; class APFloat; class APInt; +class ConstantFP; class GPtrAdd; class GStore; class GZExtLoad; @@ -351,9 +352,8 @@ /// 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); Index: llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h =================================================================== --- llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -284,6 +284,10 @@ return getMF().getFunction().getParent()->getDataLayout(); } + LLVMContext &getContext() const { + return getMF().getFunction().getContext(); + } + /// Getter for DebugLoc const DebugLoc &getDL() { return State.DL; } Index: llvm/include/llvm/Target/GlobalISel/Combine.td =================================================================== --- llvm/include/llvm/Target/GlobalISel/Combine.td +++ llvm/include/llvm/Target/GlobalISel/Combine.td @@ -461,7 +461,7 @@ >; // 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, Index: llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp =================================================================== --- llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -1289,14 +1289,10 @@ } 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 V(Val); + switch (MI.getOpcode()) { default: llvm_unreachable("Unexpected opcode!"); case TargetOpcode::G_FNEG: { @@ -1307,8 +1303,13 @@ V.clearSign(); return V; } - case TargetOpcode::G_FPTRUNC: - break; + case TargetOpcode::G_FPTRUNC: { + bool Unused; + LLT DstTy = MRI.getType(MI.getOperand(0).getReg()); + V.convert(getFltSemanticForLLT(DstTy), APFloat::rmNearestTiesToEven, + &Unused); + return V; + } case TargetOpcode::G_FSQRT: { bool Unused; V.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &Unused); @@ -1323,30 +1324,32 @@ } } // 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); + V.convert(Val.getSemantics(), APFloat::rmNearestTiesToEven, &Unused); return V; } -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(); }