Skip to content

[RISCV][GISel] Custom promote s32 G_FPTOSI/FPTOUI on RV64. #115268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 8, 2024

Conversation

topperc
Copy link
Collaborator

@topperc topperc commented Nov 7, 2024

I plan to make i32 an illegal type for RV64 to match SelectionDAG and to remove i32 from the GPR register class.

@llvmbot
Copy link
Member

llvmbot commented Nov 7, 2024

@llvm/pr-subscribers-backend-risc-v

Author: Craig Topper (topperc)

Changes

I plan to make i32 an illegal type for RV64 to match SelectionDAG and to remove i32 from the GPR register class.

Stacked on #115236


Patch is 66.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/115268.diff

23 Files Affected:

  • (modified) llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp (+27)
  • (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+27-5)
  • (modified) llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp (+4)
  • (modified) llvm/lib/Target/RISCV/RISCVCombine.td (+2-2)
  • (modified) llvm/lib/Target/RISCV/RISCVGISel.td (+3)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrGISel.td (+16)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoD.td (+2-2)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoF.td (+4-4)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td (+3-3)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll (+14-6)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll (+14-6)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-f16-rv64.mir (+4-6)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-rv64.mir (+8-12)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/itofp-f16-rv64.mir (-46)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/itofp-rv64.mir (-92)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fptoi-f16-rv64.mir (+16-24)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fptoi-rv64.mir (+32-48)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-itofp-f16-rv64.mir (+26-31)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-itofp-rv64.mir (+52-62)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fptoi-f16-rv64.mir (+8-12)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fptoi-rv64.mir (+16-24)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/itofp-f16-rv64.mir (-46)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/itofp-rv64.mir (-92)
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 389bdbe6d5e912..d11647b78d7417 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -87,6 +87,12 @@ class RISCVInstructionSelector : public InstructionSelector {
   ComplexRendererFns selectShiftMask(MachineOperand &Root) const;
   ComplexRendererFns selectAddrRegImm(MachineOperand &Root) const;
 
+  ComplexRendererFns selectSExtBits(MachineOperand &Root, unsigned Bits) const;
+  template <unsigned Bits>
+  ComplexRendererFns selectSExtBits(MachineOperand &Root) const {
+    return selectSExtBits(Root, Bits);
+  }
+
   ComplexRendererFns selectZExtBits(MachineOperand &Root, unsigned Bits) const;
   template <unsigned Bits>
   ComplexRendererFns selectZExtBits(MachineOperand &Root) const {
@@ -248,6 +254,27 @@ RISCVInstructionSelector::selectShiftMask(MachineOperand &Root) const {
   return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}};
 }
 
+InstructionSelector::ComplexRendererFns
+RISCVInstructionSelector::selectSExtBits(MachineOperand &Root,
+                                         unsigned Bits) const {
+  if (!Root.isReg())
+    return std::nullopt;
+  Register RootReg = Root.getReg();
+  MachineInstr *RootDef = MRI->getVRegDef(RootReg);
+
+  if (RootDef->getOpcode() == TargetOpcode::G_SEXT_INREG &&
+      RootDef->getOperand(2).getImm() == Bits) {
+    return {
+        {[=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); }}};
+  }
+
+  unsigned Size = MRI->getType(RootReg).getScalarSizeInBits();
+  if ((Size - KB->computeNumSignBits(RootReg)) < Bits)
+    return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
+
+  return std::nullopt;
+}
+
 InstructionSelector::ComplexRendererFns
 RISCVInstructionSelector::selectZExtBits(MachineOperand &Root,
                                          unsigned Bits) const {
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 34742394a291ed..b074cfeeacdf4a 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -533,17 +533,19 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
       .legalIf(typeIsScalarFPArith(0, ST))
       .lowerFor({s32, s64});
 
-  getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
-      .legalIf(all(typeInSet(0, {s32, sXLen}), typeIsScalarFPArith(1, ST)))
-      .widenScalarToNextPow2(0)
+  auto &FPToIActions = getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI});
+  FPToIActions.legalIf(all(typeInSet(0, {sXLen}), typeIsScalarFPArith(1, ST)));
+  if (ST.is64Bit())
+    FPToIActions.customIf(all(typeInSet(0, {s32}), typeIsScalarFPArith(1, ST)));
+  FPToIActions.widenScalarToNextPow2(0)
       .minScalar(0, s32)
       .libcallFor({{s32, s32}, {s64, s32}, {s32, s64}, {s64, s64}})
       .libcallFor(ST.is64Bit(), {{s128, s32}, {s128, s64}});
 
   getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
-      .legalIf(all(typeIsScalarFPArith(0, ST), typeInSet(1, {s32, sXLen})))
+      .legalIf(all(typeIsScalarFPArith(0, ST), typeInSet(1, {sXLen})))
       .widenScalarToNextPow2(1)
-      .minScalar(1, s32)
+      .minScalar(1, sXLen)
       .libcallFor({{s32, s32}, {s64, s32}, {s32, s64}, {s64, s64}})
       .libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}});
 
@@ -1158,6 +1160,17 @@ bool RISCVLegalizerInfo::legalizeInsertSubvector(MachineInstr &MI,
   return true;
 }
 
+static unsigned getRISCVWOpcode(unsigned Opcode) {
+  switch (Opcode) {
+  default:
+    llvm_unreachable("Unexpected opcode");
+  case TargetOpcode::G_FPTOSI:
+    return RISCV::G_FCVT_W_RV64;
+  case TargetOpcode::G_FPTOUI:
+    return RISCV::G_FCVT_WU_RV64;
+  }
+}
+
 bool RISCVLegalizerInfo::legalizeCustom(
     LegalizerHelper &Helper, MachineInstr &MI,
     LostDebugLocObserver &LocObserver) const {
@@ -1194,6 +1207,15 @@ bool RISCVLegalizerInfo::legalizeCustom(
     return Helper.lower(MI, 0, /* Unused hint type */ LLT()) ==
            LegalizerHelper::Legalized;
   }
+  case TargetOpcode::G_FPTOSI:
+  case TargetOpcode::G_FPTOUI: {
+    Helper.Observer.changingInstr(MI);
+    Helper.widenScalarDst(MI, sXLen);
+    MI.setDesc(MIRBuilder.getTII().get(getRISCVWOpcode(MI.getOpcode())));
+    MI.addOperand(MachineOperand::CreateImm(RISCVFPRndMode::RTZ));
+    Helper.Observer.changedInstr(MI);
+    return true;
+  }
   case TargetOpcode::G_IS_FPCLASS: {
     Register GISFPCLASS = MI.getOperand(0).getReg();
     Register Src = MI.getOperand(1).getReg();
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index aa06cb4d5327c9..829c0ac92c52a4 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -149,6 +149,8 @@ bool RISCVRegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
                                        const MachineRegisterInfo &MRI,
                                        const TargetRegisterInfo &TRI) const {
   switch (MI.getOpcode()) {
+  case RISCV::G_FCVT_W_RV64:
+  case RISCV::G_FCVT_WU_RV64:
   case TargetOpcode::G_FPTOSI:
   case TargetOpcode::G_FPTOUI:
   case TargetOpcode::G_FCMP:
@@ -432,6 +434,8 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
     OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = Mapping;
     break;
   }
+  case RISCV::G_FCVT_W_RV64:
+  case RISCV::G_FCVT_WU_RV64:
   case TargetOpcode::G_FPTOSI:
   case TargetOpcode::G_FPTOUI:
   case RISCV::G_FCLASS: {
diff --git a/llvm/lib/Target/RISCV/RISCVCombine.td b/llvm/lib/Target/RISCV/RISCVCombine.td
index a2e67eef03561b..60d942957c8861 100644
--- a/llvm/lib/Target/RISCV/RISCVCombine.td
+++ b/llvm/lib/Target/RISCV/RISCVCombine.td
@@ -23,6 +23,6 @@ def RISCVO0PreLegalizerCombiner: GICombiner<
 // TODO: Add more combines.
 def RISCVPostLegalizerCombiner
     : GICombiner<"RISCVPostLegalizerCombinerImpl",
-                 [redundant_and, identity_combines, commute_constant_to_rhs,
-                  constant_fold_cast_op]> {
+                 [combines_for_extload, redundant_and, identity_combines,
+                  commute_constant_to_rhs, constant_fold_cast_op]> {
 }
diff --git a/llvm/lib/Target/RISCV/RISCVGISel.td b/llvm/lib/Target/RISCV/RISCVGISel.td
index 36881b02da2e40..57ab55169e4a68 100644
--- a/llvm/lib/Target/RISCV/RISCVGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVGISel.td
@@ -96,6 +96,9 @@ def gi_sh2add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<2>">,
 def gi_sh3add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<3>">,
                       GIComplexPatternEquiv<sh3add_uw_op>;
 
+def gi_sexti32 : GIComplexOperandMatcher<s64, "selectSExtBits<32>">,
+                 GIComplexPatternEquiv<sexti32>;
+
 def gi_zexti32 : GIComplexOperandMatcher<s64, "selectZExtBits<32>">,
                  GIComplexPatternEquiv<zexti32>;
 def gi_zexti16 : GIComplexOperandMatcher<s32, "selectZExtBits<16>">,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrGISel.td b/llvm/lib/Target/RISCV/RISCVInstrGISel.td
index 763aead84dd8f4..f61fc69a3e2ea4 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrGISel.td
@@ -17,6 +17,22 @@ class RISCVGenericInstruction : GenericInstruction {
   let Namespace = "RISCV";
 }
 
+// Pseudo equivalent to a RISCVISD::FCVT_W_RV64.
+def G_FCVT_W_RV64 : RISCVGenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type1:$src, untyped_imm_0:$frm);
+  let hasSideEffects = false;
+}
+def : GINodeEquiv<G_FCVT_W_RV64, riscv_fcvt_w_rv64>;
+
+// Pseudo equivalent to a RISCVISD::FCVT_WU_RV64.
+def G_FCVT_WU_RV64 : RISCVGenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type1:$src, untyped_imm_0:$frm);
+  let hasSideEffects = false;
+}
+def : GINodeEquiv<G_FCVT_WU_RV64, riscv_fcvt_wu_rv64>;
+
 // Pseudo equivalent to a RISCVISD::FCLASS.
 def G_FCLASS : RISCVGenericInstruction {
   let OutOperandList = (outs type0:$dst);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
index 21583825405d5e..b5e1298c7770a8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
@@ -534,7 +534,7 @@ def : Pat<(store (f64 GPRPair:$rs2), (AddrRegImmINX (XLenVT GPR:$rs1), simm12:$i
           (PseudoRV32ZdinxSD GPRPair:$rs2, GPR:$rs1, simm12:$imm12)>;
 } // Predicates = [HasStdExtZdinx, IsRV32]
 
-let Predicates = [HasStdExtD] in {
+let Predicates = [HasStdExtD, IsRV32] in {
 
 // double->[u]int. Round-to-zero must be used.
 def : Pat<(i32 (any_fp_to_sint FPR64:$rs1)), (FCVT_W_D FPR64:$rs1, FRM_RTZ)>;
@@ -553,7 +553,7 @@ def : Pat<(i32 (any_lround FPR64:$rs1)), (FCVT_W_D $rs1, FRM_RMM)>;
 // [u]int->double.
 def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_D_W GPR:$rs1, FRM_RNE)>;
 def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_D_WU GPR:$rs1, FRM_RNE)>;
-} // Predicates = [HasStdExtD]
+} // Predicates = [HasStdExtD, IsRV32]
 
 let Predicates = [HasStdExtZdinx, IsRV32] in {
 
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
index da3f207a2faf72..0f2b0bb8a78c65 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
@@ -720,7 +720,7 @@ def : Pat<(f32 (bitconvert (i32 GPR:$rs1))), (EXTRACT_SUBREG GPR:$rs1, sub_32)>;
 def : Pat<(i32 (bitconvert FPR32INX:$rs1)), (INSERT_SUBREG (XLenVT (IMPLICIT_DEF)), FPR32INX:$rs1, sub_32)>;
 } // Predicates = [HasStdExtZfinx]
 
-let Predicates = [HasStdExtF] in {
+let Predicates = [HasStdExtF, IsRV32] in {
 // float->[u]int. Round-to-zero must be used.
 def : Pat<(i32 (any_fp_to_sint FPR32:$rs1)), (FCVT_W_S $rs1, FRM_RTZ)>;
 def : Pat<(i32 (any_fp_to_uint FPR32:$rs1)), (FCVT_WU_S $rs1, FRM_RTZ)>;
@@ -738,9 +738,9 @@ def : Pat<(i32 (any_lround FPR32:$rs1)), (FCVT_W_S $rs1, FRM_RMM)>;
 // [u]int->float. Match GCC and default to using dynamic rounding mode.
 def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_S_W $rs1, FRM_DYN)>;
 def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_S_WU $rs1, FRM_DYN)>;
-} // Predicates = [HasStdExtF]
+} // Predicates = [HasStdExtF, IsRV32]
 
-let Predicates = [HasStdExtZfinx] in {
+let Predicates = [HasStdExtZfinx, IsRV32] in {
 // float->[u]int. Round-to-zero must be used.
 def : Pat<(i32 (any_fp_to_sint FPR32INX:$rs1)), (FCVT_W_S_INX $rs1, FRM_RTZ)>;
 def : Pat<(i32 (any_fp_to_uint FPR32INX:$rs1)), (FCVT_WU_S_INX $rs1, FRM_RTZ)>;
@@ -758,7 +758,7 @@ def : Pat<(i32 (any_lround FPR32INX:$rs1)), (FCVT_W_S_INX $rs1, FRM_RMM)>;
 // [u]int->float. Match GCC and default to using dynamic rounding mode.
 def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_S_W_INX $rs1, FRM_DYN)>;
 def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_S_WU_INX $rs1, FRM_DYN)>;
-} // Predicates = [HasStdExtZfinx]
+} // Predicates = [HasStdExtZfinx, IsRV32]
 
 let Predicates = [HasStdExtF, IsRV64] in {
 // Moves (no conversion)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
index 0d3127e0d5abeb..ccf13e07ef193f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
@@ -480,7 +480,7 @@ def : Pat<(riscv_fmv_x_anyexth FPR16INX:$src), (INSERT_SUBREG (XLenVT (IMPLICIT_
 def : Pat<(fcopysign FPR32INX:$rs1, FPR16INX:$rs2), (FSGNJ_S_INX $rs1, (FCVT_S_H_INX $rs2, FRM_RNE))>;
 } // Predicates = [HasStdExtZhinxmin]
 
-let Predicates = [HasStdExtZfh] in {
+let Predicates = [HasStdExtZfh, IsRV32] in {
 // half->[u]int. Round-to-zero must be used.
 def : Pat<(i32 (any_fp_to_sint (f16 FPR16:$rs1))), (FCVT_W_H $rs1, 0b001)>;
 def : Pat<(i32 (any_fp_to_uint (f16 FPR16:$rs1))), (FCVT_WU_H $rs1, 0b001)>;
@@ -500,7 +500,7 @@ def : Pat<(f16 (any_sint_to_fp (i32 GPR:$rs1))), (FCVT_H_W $rs1, FRM_DYN)>;
 def : Pat<(f16 (any_uint_to_fp (i32 GPR:$rs1))), (FCVT_H_WU $rs1, FRM_DYN)>;
 } // Predicates = [HasStdExtZfh]
 
-let Predicates = [HasStdExtZhinx] in {
+let Predicates = [HasStdExtZhinx, IsRV32] in {
 // half->[u]int. Round-to-zero must be used.
 def : Pat<(i32 (any_fp_to_sint FPR16INX:$rs1)), (FCVT_W_H_INX $rs1, 0b001)>;
 def : Pat<(i32 (any_fp_to_uint FPR16INX:$rs1)), (FCVT_WU_H_INX $rs1, 0b001)>;
@@ -518,7 +518,7 @@ def : Pat<(i32 (any_lround FPR16INX:$rs1)), (FCVT_W_H_INX $rs1, FRM_RMM)>;
 // [u]int->half. Match GCC and default to using dynamic rounding mode.
 def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_H_W_INX $rs1, FRM_DYN)>;
 def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_H_WU_INX $rs1, FRM_DYN)>;
-} // Predicates = [HasStdExtZhinx]
+} // Predicates = [HasStdExtZhinx, IsRV32]
 
 let Predicates = [HasStdExtZfh, IsRV64] in {
 // Use target specific isd nodes to help us remember the result is sign
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll b/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
index 785cc2aafde11b..0e5cbe63004b62 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
@@ -98,11 +98,17 @@ define double @fcvt_d_wu(i32 %a) nounwind {
 }
 
 define double @fcvt_d_wu_load(ptr %p) nounwind {
-; CHECKIFD-LABEL: fcvt_d_wu_load:
-; CHECKIFD:       # %bb.0:
-; CHECKIFD-NEXT:    lw a0, 0(a0)
-; CHECKIFD-NEXT:    fcvt.d.wu fa0, a0
-; CHECKIFD-NEXT:    ret
+; RV32IFD-LABEL: fcvt_d_wu_load:
+; RV32IFD:       # %bb.0:
+; RV32IFD-NEXT:    lw a0, 0(a0)
+; RV32IFD-NEXT:    fcvt.d.wu fa0, a0
+; RV32IFD-NEXT:    ret
+;
+; RV64IFD-LABEL: fcvt_d_wu_load:
+; RV64IFD:       # %bb.0:
+; RV64IFD-NEXT:    lwu a0, 0(a0)
+; RV64IFD-NEXT:    fcvt.d.wu fa0, a0
+; RV64IFD-NEXT:    ret
   %a = load i32, ptr %p
   %1 = uitofp i32 %a to double
   ret double %1
@@ -294,7 +300,9 @@ define signext i32 @fcvt_d_wu_demanded_bits(i32 signext %0, ptr %1) nounwind {
 ; RV64IFD-LABEL: fcvt_d_wu_demanded_bits:
 ; RV64IFD:       # %bb.0:
 ; RV64IFD-NEXT:    addiw a0, a0, 1
-; RV64IFD-NEXT:    fcvt.d.wu fa5, a0
+; RV64IFD-NEXT:    slli a2, a0, 32
+; RV64IFD-NEXT:    srli a2, a2, 32
+; RV64IFD-NEXT:    fcvt.d.wu fa5, a2
 ; RV64IFD-NEXT:    fsd fa5, 0(a1)
 ; RV64IFD-NEXT:    ret
   %3 = add i32 %0, 1
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll b/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
index d6a36c5a702ac8..c5a36d063c0ad6 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
@@ -101,11 +101,17 @@ define float @fcvt_s_wu(i32 %a) nounwind {
 }
 
 define float @fcvt_s_wu_load(ptr %p) nounwind {
-; CHECKIF-LABEL: fcvt_s_wu_load:
-; CHECKIF:       # %bb.0:
-; CHECKIF-NEXT:    lw a0, 0(a0)
-; CHECKIF-NEXT:    fcvt.s.wu fa0, a0
-; CHECKIF-NEXT:    ret
+; RV32IF-LABEL: fcvt_s_wu_load:
+; RV32IF:       # %bb.0:
+; RV32IF-NEXT:    lw a0, 0(a0)
+; RV32IF-NEXT:    fcvt.s.wu fa0, a0
+; RV32IF-NEXT:    ret
+;
+; RV64IF-LABEL: fcvt_s_wu_load:
+; RV64IF:       # %bb.0:
+; RV64IF-NEXT:    lwu a0, 0(a0)
+; RV64IF-NEXT:    fcvt.s.wu fa0, a0
+; RV64IF-NEXT:    ret
   %a = load i32, ptr %p
   %1 = uitofp i32 %a to float
   ret float %1
@@ -266,7 +272,9 @@ define signext i32 @fcvt_s_wu_demanded_bits(i32 signext %0, ptr %1) nounwind {
 ; RV64IF-LABEL: fcvt_s_wu_demanded_bits:
 ; RV64IF:       # %bb.0:
 ; RV64IF-NEXT:    addiw a0, a0, 1
-; RV64IF-NEXT:    fcvt.s.wu fa5, a0
+; RV64IF-NEXT:    slli a2, a0, 32
+; RV64IF-NEXT:    srli a2, a2, 32
+; RV64IF-NEXT:    fcvt.s.wu fa5, a2
 ; RV64IF-NEXT:    fsw fa5, 0(a1)
 ; RV64IF-NEXT:    ret
   %3 = add i32 %0, 1
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-f16-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-f16-rv64.mir
index 11a3f47ea7f14e..eb5558b872698c 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-f16-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-f16-rv64.mir
@@ -19,9 +19,8 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[FCVT_W_H]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:fprb(s16) = COPY $f10_h
-    %1:gprb(s32) = G_FPTOSI %0(s16)
-    %2:gprb(s64) = G_ANYEXT %1(s32)
-    $x10 = COPY %2(s64)
+    %1:gprb(s64) = G_FCVT_W_RV64 %0(s16), 1
+    $x10 = COPY %1(s64)
     PseudoRET implicit $x10
 
 ...
@@ -42,9 +41,8 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[FCVT_WU_H]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:fprb(s16) = COPY $f10_h
-    %1:gprb(s32) = G_FPTOUI %0(s16)
-    %2:gprb(s64) = G_ANYEXT %1(s32)
-    $x10 = COPY %2(s64)
+    %1:gprb(s64) = G_FCVT_WU_RV64 %0(s16), 1
+    $x10 = COPY %1(s64)
     PseudoRET implicit $x10
 
 ...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-rv64.mir
index afa53c8de76db9..9c3b306cd3394f 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-rv64.mir
@@ -19,9 +19,8 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[FCVT_W_S]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:fprb(s32) = COPY $f10_f
-    %1:gprb(s32) = G_FPTOSI %0(s32)
-    %2:gprb(s64) = G_ANYEXT %1(s32)
-    $x10 = COPY %2(s64)
+    %1:gprb(s64) = G_FCVT_W_RV64 %0(s32), 1
+    $x10 = COPY %1(s64)
     PseudoRET implicit $x10
 
 ...
@@ -42,9 +41,8 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[FCVT_WU_S]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:fprb(s32) = COPY $f10_f
-    %1:gprb(s32) = G_FPTOUI %0(s32)
-    %2:gprb(s64) = G_ANYEXT %1(s32)
-    $x10 = COPY %2(s64)
+    %1:gprb(s64) = G_FCVT_WU_RV64 %0(s32), 1
+    $x10 = COPY %1(s64)
     PseudoRET implicit $x10
 
 ...
@@ -109,9 +107,8 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[FCVT_W_D]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:fprb(s64) = COPY $f10_d
-    %1:gprb(s32) = G_FPTOSI %0(s64)
-    %2:gprb(s64) = G_ANYEXT %1(s32)
-    $x10 = COPY %2(s64)
+    %1:gprb(s64) = G_FCVT_W_RV64 %0(s64), 1
+    $x10 = COPY %1(s64)
     PseudoRET implicit $x10
 
 ...
@@ -132,9 +129,8 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[FCVT_WU_D]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:fprb(s64) = COPY $f10_d
-    %1:gprb(s32) = G_FPTOUI %0(s64)
-    %2:gprb(s64) = G_ANYEXT %1(s32)
-    $x10 = COPY %2(s64)
+    %1:gprb(s64) = G_FCVT_WU_RV64 %0(s64), 1
+    $x10 = COPY %1(s64)
     PseudoRET implicit $x10
 
 ...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/itofp-f16-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/itofp-f16-rv64.mir
index 1afb1d9be6a099..b813a79c339ec5 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/itofp-f16-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/itofp-f16-rv64.mir
@@ -2,52 +2,6 @@
 # RUN: llc -mtriple=riscv64 -mattr=+zfh -run-pass=instruction-select \
 # RUN:   -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
 
----
-name:            sitofp_s64_s32
-legalized:       true
-regBankSelected: true
-tracksRegLiveness: true
-body:             |
-  bb.0:
-    liveins: $x10
-
-    ; CHECK-LABEL: name: sitofp_s64_s32
-    ; CHECK: liveins: $x10
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
-    ; CHECK-NEXT: [[FCVT_H_W:%[0-9]+]]:fpr16 = nofpexcept FCVT_H_W [[COPY]], 7
-    ; CHECK-NEXT: $f10_h = COPY [[FCVT_H_W]]
-    ; CHECK-NEXT: PseudoRET implicit $f10_h
-    %0:gprb(s64) = COPY $x10
-    %1:gprb(s32) = G_TRUNC %0(s64)
-    %2:fprb(s16) = G_SITOFP %1(s32)
-    $f10_h = COPY %2(s16)
-    PseudoRET implicit $f10_h
-
-...
----
-name:            uitofp_s64_s32
-legalized:       true
-regBankSelected: true
-tracksRegLiveness: true
-body:             |
-  bb.0:
-    liveins: $x10
-
-    ; CHECK-LABEL: name: uitofp_s64_s32
-    ; CHECK: liveins: $x10
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
-    ; CHECK-NEXT: [[FCVT_H_WU:%[0-9]+]]:fpr16 = nofpexcept FCVT_H_WU [[COPY]], 7
-    ; CHECK-NEXT: $f10_h = COPY [[FCVT_H_WU]]
-    ; CHECK-NEXT: PseudoRET implicit $f10_h
-    %0:gprb(s64) = COPY $x10
-    %1:gprb(s32) = G_TRUNC %0(s64)
-    %2:fprb(s16) = G_UITOFP %1(s32)
-    $f10_h = COPY %2(s16)
-    PseudoRET implicit $f10_h
-
-...
 ---
 name:            sitofp_s64_s64
 legalized:       true
diff --git a/llvm/test/CodeGen/RISCV/GlobalIS...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Nov 7, 2024

@llvm/pr-subscribers-llvm-globalisel

Author: Craig Topper (topperc)

Changes

I plan to make i32 an illegal type for RV64 to match SelectionDAG and to remove i32 from the GPR register class.

Stacked on #115236


Patch is 66.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/115268.diff

23 Files Affected:

  • (modified) llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp (+27)
  • (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+27-5)
  • (modified) llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp (+4)
  • (modified) llvm/lib/Target/RISCV/RISCVCombine.td (+2-2)
  • (modified) llvm/lib/Target/RISCV/RISCVGISel.td (+3)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrGISel.td (+16)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoD.td (+2-2)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoF.td (+4-4)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td (+3-3)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll (+14-6)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll (+14-6)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-f16-rv64.mir (+4-6)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-rv64.mir (+8-12)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/itofp-f16-rv64.mir (-46)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/itofp-rv64.mir (-92)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fptoi-f16-rv64.mir (+16-24)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fptoi-rv64.mir (+32-48)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-itofp-f16-rv64.mir (+26-31)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-itofp-rv64.mir (+52-62)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fptoi-f16-rv64.mir (+8-12)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fptoi-rv64.mir (+16-24)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/itofp-f16-rv64.mir (-46)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/itofp-rv64.mir (-92)
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 389bdbe6d5e912..d11647b78d7417 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -87,6 +87,12 @@ class RISCVInstructionSelector : public InstructionSelector {
   ComplexRendererFns selectShiftMask(MachineOperand &Root) const;
   ComplexRendererFns selectAddrRegImm(MachineOperand &Root) const;
 
+  ComplexRendererFns selectSExtBits(MachineOperand &Root, unsigned Bits) const;
+  template <unsigned Bits>
+  ComplexRendererFns selectSExtBits(MachineOperand &Root) const {
+    return selectSExtBits(Root, Bits);
+  }
+
   ComplexRendererFns selectZExtBits(MachineOperand &Root, unsigned Bits) const;
   template <unsigned Bits>
   ComplexRendererFns selectZExtBits(MachineOperand &Root) const {
@@ -248,6 +254,27 @@ RISCVInstructionSelector::selectShiftMask(MachineOperand &Root) const {
   return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}};
 }
 
+InstructionSelector::ComplexRendererFns
+RISCVInstructionSelector::selectSExtBits(MachineOperand &Root,
+                                         unsigned Bits) const {
+  if (!Root.isReg())
+    return std::nullopt;
+  Register RootReg = Root.getReg();
+  MachineInstr *RootDef = MRI->getVRegDef(RootReg);
+
+  if (RootDef->getOpcode() == TargetOpcode::G_SEXT_INREG &&
+      RootDef->getOperand(2).getImm() == Bits) {
+    return {
+        {[=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); }}};
+  }
+
+  unsigned Size = MRI->getType(RootReg).getScalarSizeInBits();
+  if ((Size - KB->computeNumSignBits(RootReg)) < Bits)
+    return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
+
+  return std::nullopt;
+}
+
 InstructionSelector::ComplexRendererFns
 RISCVInstructionSelector::selectZExtBits(MachineOperand &Root,
                                          unsigned Bits) const {
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 34742394a291ed..b074cfeeacdf4a 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -533,17 +533,19 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
       .legalIf(typeIsScalarFPArith(0, ST))
       .lowerFor({s32, s64});
 
-  getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
-      .legalIf(all(typeInSet(0, {s32, sXLen}), typeIsScalarFPArith(1, ST)))
-      .widenScalarToNextPow2(0)
+  auto &FPToIActions = getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI});
+  FPToIActions.legalIf(all(typeInSet(0, {sXLen}), typeIsScalarFPArith(1, ST)));
+  if (ST.is64Bit())
+    FPToIActions.customIf(all(typeInSet(0, {s32}), typeIsScalarFPArith(1, ST)));
+  FPToIActions.widenScalarToNextPow2(0)
       .minScalar(0, s32)
       .libcallFor({{s32, s32}, {s64, s32}, {s32, s64}, {s64, s64}})
       .libcallFor(ST.is64Bit(), {{s128, s32}, {s128, s64}});
 
   getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
-      .legalIf(all(typeIsScalarFPArith(0, ST), typeInSet(1, {s32, sXLen})))
+      .legalIf(all(typeIsScalarFPArith(0, ST), typeInSet(1, {sXLen})))
       .widenScalarToNextPow2(1)
-      .minScalar(1, s32)
+      .minScalar(1, sXLen)
       .libcallFor({{s32, s32}, {s64, s32}, {s32, s64}, {s64, s64}})
       .libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}});
 
@@ -1158,6 +1160,17 @@ bool RISCVLegalizerInfo::legalizeInsertSubvector(MachineInstr &MI,
   return true;
 }
 
+static unsigned getRISCVWOpcode(unsigned Opcode) {
+  switch (Opcode) {
+  default:
+    llvm_unreachable("Unexpected opcode");
+  case TargetOpcode::G_FPTOSI:
+    return RISCV::G_FCVT_W_RV64;
+  case TargetOpcode::G_FPTOUI:
+    return RISCV::G_FCVT_WU_RV64;
+  }
+}
+
 bool RISCVLegalizerInfo::legalizeCustom(
     LegalizerHelper &Helper, MachineInstr &MI,
     LostDebugLocObserver &LocObserver) const {
@@ -1194,6 +1207,15 @@ bool RISCVLegalizerInfo::legalizeCustom(
     return Helper.lower(MI, 0, /* Unused hint type */ LLT()) ==
            LegalizerHelper::Legalized;
   }
+  case TargetOpcode::G_FPTOSI:
+  case TargetOpcode::G_FPTOUI: {
+    Helper.Observer.changingInstr(MI);
+    Helper.widenScalarDst(MI, sXLen);
+    MI.setDesc(MIRBuilder.getTII().get(getRISCVWOpcode(MI.getOpcode())));
+    MI.addOperand(MachineOperand::CreateImm(RISCVFPRndMode::RTZ));
+    Helper.Observer.changedInstr(MI);
+    return true;
+  }
   case TargetOpcode::G_IS_FPCLASS: {
     Register GISFPCLASS = MI.getOperand(0).getReg();
     Register Src = MI.getOperand(1).getReg();
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index aa06cb4d5327c9..829c0ac92c52a4 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -149,6 +149,8 @@ bool RISCVRegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
                                        const MachineRegisterInfo &MRI,
                                        const TargetRegisterInfo &TRI) const {
   switch (MI.getOpcode()) {
+  case RISCV::G_FCVT_W_RV64:
+  case RISCV::G_FCVT_WU_RV64:
   case TargetOpcode::G_FPTOSI:
   case TargetOpcode::G_FPTOUI:
   case TargetOpcode::G_FCMP:
@@ -432,6 +434,8 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
     OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = Mapping;
     break;
   }
+  case RISCV::G_FCVT_W_RV64:
+  case RISCV::G_FCVT_WU_RV64:
   case TargetOpcode::G_FPTOSI:
   case TargetOpcode::G_FPTOUI:
   case RISCV::G_FCLASS: {
diff --git a/llvm/lib/Target/RISCV/RISCVCombine.td b/llvm/lib/Target/RISCV/RISCVCombine.td
index a2e67eef03561b..60d942957c8861 100644
--- a/llvm/lib/Target/RISCV/RISCVCombine.td
+++ b/llvm/lib/Target/RISCV/RISCVCombine.td
@@ -23,6 +23,6 @@ def RISCVO0PreLegalizerCombiner: GICombiner<
 // TODO: Add more combines.
 def RISCVPostLegalizerCombiner
     : GICombiner<"RISCVPostLegalizerCombinerImpl",
-                 [redundant_and, identity_combines, commute_constant_to_rhs,
-                  constant_fold_cast_op]> {
+                 [combines_for_extload, redundant_and, identity_combines,
+                  commute_constant_to_rhs, constant_fold_cast_op]> {
 }
diff --git a/llvm/lib/Target/RISCV/RISCVGISel.td b/llvm/lib/Target/RISCV/RISCVGISel.td
index 36881b02da2e40..57ab55169e4a68 100644
--- a/llvm/lib/Target/RISCV/RISCVGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVGISel.td
@@ -96,6 +96,9 @@ def gi_sh2add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<2>">,
 def gi_sh3add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<3>">,
                       GIComplexPatternEquiv<sh3add_uw_op>;
 
+def gi_sexti32 : GIComplexOperandMatcher<s64, "selectSExtBits<32>">,
+                 GIComplexPatternEquiv<sexti32>;
+
 def gi_zexti32 : GIComplexOperandMatcher<s64, "selectZExtBits<32>">,
                  GIComplexPatternEquiv<zexti32>;
 def gi_zexti16 : GIComplexOperandMatcher<s32, "selectZExtBits<16>">,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrGISel.td b/llvm/lib/Target/RISCV/RISCVInstrGISel.td
index 763aead84dd8f4..f61fc69a3e2ea4 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrGISel.td
@@ -17,6 +17,22 @@ class RISCVGenericInstruction : GenericInstruction {
   let Namespace = "RISCV";
 }
 
+// Pseudo equivalent to a RISCVISD::FCVT_W_RV64.
+def G_FCVT_W_RV64 : RISCVGenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type1:$src, untyped_imm_0:$frm);
+  let hasSideEffects = false;
+}
+def : GINodeEquiv<G_FCVT_W_RV64, riscv_fcvt_w_rv64>;
+
+// Pseudo equivalent to a RISCVISD::FCVT_WU_RV64.
+def G_FCVT_WU_RV64 : RISCVGenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type1:$src, untyped_imm_0:$frm);
+  let hasSideEffects = false;
+}
+def : GINodeEquiv<G_FCVT_WU_RV64, riscv_fcvt_wu_rv64>;
+
 // Pseudo equivalent to a RISCVISD::FCLASS.
 def G_FCLASS : RISCVGenericInstruction {
   let OutOperandList = (outs type0:$dst);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
index 21583825405d5e..b5e1298c7770a8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
@@ -534,7 +534,7 @@ def : Pat<(store (f64 GPRPair:$rs2), (AddrRegImmINX (XLenVT GPR:$rs1), simm12:$i
           (PseudoRV32ZdinxSD GPRPair:$rs2, GPR:$rs1, simm12:$imm12)>;
 } // Predicates = [HasStdExtZdinx, IsRV32]
 
-let Predicates = [HasStdExtD] in {
+let Predicates = [HasStdExtD, IsRV32] in {
 
 // double->[u]int. Round-to-zero must be used.
 def : Pat<(i32 (any_fp_to_sint FPR64:$rs1)), (FCVT_W_D FPR64:$rs1, FRM_RTZ)>;
@@ -553,7 +553,7 @@ def : Pat<(i32 (any_lround FPR64:$rs1)), (FCVT_W_D $rs1, FRM_RMM)>;
 // [u]int->double.
 def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_D_W GPR:$rs1, FRM_RNE)>;
 def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_D_WU GPR:$rs1, FRM_RNE)>;
-} // Predicates = [HasStdExtD]
+} // Predicates = [HasStdExtD, IsRV32]
 
 let Predicates = [HasStdExtZdinx, IsRV32] in {
 
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
index da3f207a2faf72..0f2b0bb8a78c65 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
@@ -720,7 +720,7 @@ def : Pat<(f32 (bitconvert (i32 GPR:$rs1))), (EXTRACT_SUBREG GPR:$rs1, sub_32)>;
 def : Pat<(i32 (bitconvert FPR32INX:$rs1)), (INSERT_SUBREG (XLenVT (IMPLICIT_DEF)), FPR32INX:$rs1, sub_32)>;
 } // Predicates = [HasStdExtZfinx]
 
-let Predicates = [HasStdExtF] in {
+let Predicates = [HasStdExtF, IsRV32] in {
 // float->[u]int. Round-to-zero must be used.
 def : Pat<(i32 (any_fp_to_sint FPR32:$rs1)), (FCVT_W_S $rs1, FRM_RTZ)>;
 def : Pat<(i32 (any_fp_to_uint FPR32:$rs1)), (FCVT_WU_S $rs1, FRM_RTZ)>;
@@ -738,9 +738,9 @@ def : Pat<(i32 (any_lround FPR32:$rs1)), (FCVT_W_S $rs1, FRM_RMM)>;
 // [u]int->float. Match GCC and default to using dynamic rounding mode.
 def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_S_W $rs1, FRM_DYN)>;
 def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_S_WU $rs1, FRM_DYN)>;
-} // Predicates = [HasStdExtF]
+} // Predicates = [HasStdExtF, IsRV32]
 
-let Predicates = [HasStdExtZfinx] in {
+let Predicates = [HasStdExtZfinx, IsRV32] in {
 // float->[u]int. Round-to-zero must be used.
 def : Pat<(i32 (any_fp_to_sint FPR32INX:$rs1)), (FCVT_W_S_INX $rs1, FRM_RTZ)>;
 def : Pat<(i32 (any_fp_to_uint FPR32INX:$rs1)), (FCVT_WU_S_INX $rs1, FRM_RTZ)>;
@@ -758,7 +758,7 @@ def : Pat<(i32 (any_lround FPR32INX:$rs1)), (FCVT_W_S_INX $rs1, FRM_RMM)>;
 // [u]int->float. Match GCC and default to using dynamic rounding mode.
 def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_S_W_INX $rs1, FRM_DYN)>;
 def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_S_WU_INX $rs1, FRM_DYN)>;
-} // Predicates = [HasStdExtZfinx]
+} // Predicates = [HasStdExtZfinx, IsRV32]
 
 let Predicates = [HasStdExtF, IsRV64] in {
 // Moves (no conversion)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
index 0d3127e0d5abeb..ccf13e07ef193f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
@@ -480,7 +480,7 @@ def : Pat<(riscv_fmv_x_anyexth FPR16INX:$src), (INSERT_SUBREG (XLenVT (IMPLICIT_
 def : Pat<(fcopysign FPR32INX:$rs1, FPR16INX:$rs2), (FSGNJ_S_INX $rs1, (FCVT_S_H_INX $rs2, FRM_RNE))>;
 } // Predicates = [HasStdExtZhinxmin]
 
-let Predicates = [HasStdExtZfh] in {
+let Predicates = [HasStdExtZfh, IsRV32] in {
 // half->[u]int. Round-to-zero must be used.
 def : Pat<(i32 (any_fp_to_sint (f16 FPR16:$rs1))), (FCVT_W_H $rs1, 0b001)>;
 def : Pat<(i32 (any_fp_to_uint (f16 FPR16:$rs1))), (FCVT_WU_H $rs1, 0b001)>;
@@ -500,7 +500,7 @@ def : Pat<(f16 (any_sint_to_fp (i32 GPR:$rs1))), (FCVT_H_W $rs1, FRM_DYN)>;
 def : Pat<(f16 (any_uint_to_fp (i32 GPR:$rs1))), (FCVT_H_WU $rs1, FRM_DYN)>;
 } // Predicates = [HasStdExtZfh]
 
-let Predicates = [HasStdExtZhinx] in {
+let Predicates = [HasStdExtZhinx, IsRV32] in {
 // half->[u]int. Round-to-zero must be used.
 def : Pat<(i32 (any_fp_to_sint FPR16INX:$rs1)), (FCVT_W_H_INX $rs1, 0b001)>;
 def : Pat<(i32 (any_fp_to_uint FPR16INX:$rs1)), (FCVT_WU_H_INX $rs1, 0b001)>;
@@ -518,7 +518,7 @@ def : Pat<(i32 (any_lround FPR16INX:$rs1)), (FCVT_W_H_INX $rs1, FRM_RMM)>;
 // [u]int->half. Match GCC and default to using dynamic rounding mode.
 def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_H_W_INX $rs1, FRM_DYN)>;
 def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_H_WU_INX $rs1, FRM_DYN)>;
-} // Predicates = [HasStdExtZhinx]
+} // Predicates = [HasStdExtZhinx, IsRV32]
 
 let Predicates = [HasStdExtZfh, IsRV64] in {
 // Use target specific isd nodes to help us remember the result is sign
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll b/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
index 785cc2aafde11b..0e5cbe63004b62 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
@@ -98,11 +98,17 @@ define double @fcvt_d_wu(i32 %a) nounwind {
 }
 
 define double @fcvt_d_wu_load(ptr %p) nounwind {
-; CHECKIFD-LABEL: fcvt_d_wu_load:
-; CHECKIFD:       # %bb.0:
-; CHECKIFD-NEXT:    lw a0, 0(a0)
-; CHECKIFD-NEXT:    fcvt.d.wu fa0, a0
-; CHECKIFD-NEXT:    ret
+; RV32IFD-LABEL: fcvt_d_wu_load:
+; RV32IFD:       # %bb.0:
+; RV32IFD-NEXT:    lw a0, 0(a0)
+; RV32IFD-NEXT:    fcvt.d.wu fa0, a0
+; RV32IFD-NEXT:    ret
+;
+; RV64IFD-LABEL: fcvt_d_wu_load:
+; RV64IFD:       # %bb.0:
+; RV64IFD-NEXT:    lwu a0, 0(a0)
+; RV64IFD-NEXT:    fcvt.d.wu fa0, a0
+; RV64IFD-NEXT:    ret
   %a = load i32, ptr %p
   %1 = uitofp i32 %a to double
   ret double %1
@@ -294,7 +300,9 @@ define signext i32 @fcvt_d_wu_demanded_bits(i32 signext %0, ptr %1) nounwind {
 ; RV64IFD-LABEL: fcvt_d_wu_demanded_bits:
 ; RV64IFD:       # %bb.0:
 ; RV64IFD-NEXT:    addiw a0, a0, 1
-; RV64IFD-NEXT:    fcvt.d.wu fa5, a0
+; RV64IFD-NEXT:    slli a2, a0, 32
+; RV64IFD-NEXT:    srli a2, a2, 32
+; RV64IFD-NEXT:    fcvt.d.wu fa5, a2
 ; RV64IFD-NEXT:    fsd fa5, 0(a1)
 ; RV64IFD-NEXT:    ret
   %3 = add i32 %0, 1
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll b/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
index d6a36c5a702ac8..c5a36d063c0ad6 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
@@ -101,11 +101,17 @@ define float @fcvt_s_wu(i32 %a) nounwind {
 }
 
 define float @fcvt_s_wu_load(ptr %p) nounwind {
-; CHECKIF-LABEL: fcvt_s_wu_load:
-; CHECKIF:       # %bb.0:
-; CHECKIF-NEXT:    lw a0, 0(a0)
-; CHECKIF-NEXT:    fcvt.s.wu fa0, a0
-; CHECKIF-NEXT:    ret
+; RV32IF-LABEL: fcvt_s_wu_load:
+; RV32IF:       # %bb.0:
+; RV32IF-NEXT:    lw a0, 0(a0)
+; RV32IF-NEXT:    fcvt.s.wu fa0, a0
+; RV32IF-NEXT:    ret
+;
+; RV64IF-LABEL: fcvt_s_wu_load:
+; RV64IF:       # %bb.0:
+; RV64IF-NEXT:    lwu a0, 0(a0)
+; RV64IF-NEXT:    fcvt.s.wu fa0, a0
+; RV64IF-NEXT:    ret
   %a = load i32, ptr %p
   %1 = uitofp i32 %a to float
   ret float %1
@@ -266,7 +272,9 @@ define signext i32 @fcvt_s_wu_demanded_bits(i32 signext %0, ptr %1) nounwind {
 ; RV64IF-LABEL: fcvt_s_wu_demanded_bits:
 ; RV64IF:       # %bb.0:
 ; RV64IF-NEXT:    addiw a0, a0, 1
-; RV64IF-NEXT:    fcvt.s.wu fa5, a0
+; RV64IF-NEXT:    slli a2, a0, 32
+; RV64IF-NEXT:    srli a2, a2, 32
+; RV64IF-NEXT:    fcvt.s.wu fa5, a2
 ; RV64IF-NEXT:    fsw fa5, 0(a1)
 ; RV64IF-NEXT:    ret
   %3 = add i32 %0, 1
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-f16-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-f16-rv64.mir
index 11a3f47ea7f14e..eb5558b872698c 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-f16-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-f16-rv64.mir
@@ -19,9 +19,8 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[FCVT_W_H]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:fprb(s16) = COPY $f10_h
-    %1:gprb(s32) = G_FPTOSI %0(s16)
-    %2:gprb(s64) = G_ANYEXT %1(s32)
-    $x10 = COPY %2(s64)
+    %1:gprb(s64) = G_FCVT_W_RV64 %0(s16), 1
+    $x10 = COPY %1(s64)
     PseudoRET implicit $x10
 
 ...
@@ -42,9 +41,8 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[FCVT_WU_H]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:fprb(s16) = COPY $f10_h
-    %1:gprb(s32) = G_FPTOUI %0(s16)
-    %2:gprb(s64) = G_ANYEXT %1(s32)
-    $x10 = COPY %2(s64)
+    %1:gprb(s64) = G_FCVT_WU_RV64 %0(s16), 1
+    $x10 = COPY %1(s64)
     PseudoRET implicit $x10
 
 ...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-rv64.mir
index afa53c8de76db9..9c3b306cd3394f 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fptoi-rv64.mir
@@ -19,9 +19,8 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[FCVT_W_S]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:fprb(s32) = COPY $f10_f
-    %1:gprb(s32) = G_FPTOSI %0(s32)
-    %2:gprb(s64) = G_ANYEXT %1(s32)
-    $x10 = COPY %2(s64)
+    %1:gprb(s64) = G_FCVT_W_RV64 %0(s32), 1
+    $x10 = COPY %1(s64)
     PseudoRET implicit $x10
 
 ...
@@ -42,9 +41,8 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[FCVT_WU_S]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:fprb(s32) = COPY $f10_f
-    %1:gprb(s32) = G_FPTOUI %0(s32)
-    %2:gprb(s64) = G_ANYEXT %1(s32)
-    $x10 = COPY %2(s64)
+    %1:gprb(s64) = G_FCVT_WU_RV64 %0(s32), 1
+    $x10 = COPY %1(s64)
     PseudoRET implicit $x10
 
 ...
@@ -109,9 +107,8 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[FCVT_W_D]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:fprb(s64) = COPY $f10_d
-    %1:gprb(s32) = G_FPTOSI %0(s64)
-    %2:gprb(s64) = G_ANYEXT %1(s32)
-    $x10 = COPY %2(s64)
+    %1:gprb(s64) = G_FCVT_W_RV64 %0(s64), 1
+    $x10 = COPY %1(s64)
     PseudoRET implicit $x10
 
 ...
@@ -132,9 +129,8 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[FCVT_WU_D]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:fprb(s64) = COPY $f10_d
-    %1:gprb(s32) = G_FPTOUI %0(s64)
-    %2:gprb(s64) = G_ANYEXT %1(s32)
-    $x10 = COPY %2(s64)
+    %1:gprb(s64) = G_FCVT_WU_RV64 %0(s64), 1
+    $x10 = COPY %1(s64)
     PseudoRET implicit $x10
 
 ...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/itofp-f16-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/itofp-f16-rv64.mir
index 1afb1d9be6a099..b813a79c339ec5 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/itofp-f16-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/itofp-f16-rv64.mir
@@ -2,52 +2,6 @@
 # RUN: llc -mtriple=riscv64 -mattr=+zfh -run-pass=instruction-select \
 # RUN:   -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
 
----
-name:            sitofp_s64_s32
-legalized:       true
-regBankSelected: true
-tracksRegLiveness: true
-body:             |
-  bb.0:
-    liveins: $x10
-
-    ; CHECK-LABEL: name: sitofp_s64_s32
-    ; CHECK: liveins: $x10
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
-    ; CHECK-NEXT: [[FCVT_H_W:%[0-9]+]]:fpr16 = nofpexcept FCVT_H_W [[COPY]], 7
-    ; CHECK-NEXT: $f10_h = COPY [[FCVT_H_W]]
-    ; CHECK-NEXT: PseudoRET implicit $f10_h
-    %0:gprb(s64) = COPY $x10
-    %1:gprb(s32) = G_TRUNC %0(s64)
-    %2:fprb(s16) = G_SITOFP %1(s32)
-    $f10_h = COPY %2(s16)
-    PseudoRET implicit $f10_h
-
-...
----
-name:            uitofp_s64_s32
-legalized:       true
-regBankSelected: true
-tracksRegLiveness: true
-body:             |
-  bb.0:
-    liveins: $x10
-
-    ; CHECK-LABEL: name: uitofp_s64_s32
-    ; CHECK: liveins: $x10
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
-    ; CHECK-NEXT: [[FCVT_H_WU:%[0-9]+]]:fpr16 = nofpexcept FCVT_H_WU [[COPY]], 7
-    ; CHECK-NEXT: $f10_h = COPY [[FCVT_H_WU]]
-    ; CHECK-NEXT: PseudoRET implicit $f10_h
-    %0:gprb(s64) = COPY $x10
-    %1:gprb(s32) = G_TRUNC %0(s64)
-    %2:fprb(s16) = G_UITOFP %1(s32)
-    $f10_h = COPY %2(s16)
-    PseudoRET implicit $f10_h
-
-...
 ---
 name:            sitofp_s64_s64
 legalized:       true
diff --git a/llvm/test/CodeGen/RISCV/GlobalIS...
[truncated]

Copy link
Member

@mshockwave mshockwave left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@topperc topperc merged commit d3177d8 into llvm:main Nov 8, 2024
6 of 8 checks passed
@topperc topperc deleted the pr/gisel-fptoi branch November 8, 2024 01:09
Groverkss pushed a commit to iree-org/llvm-project that referenced this pull request Nov 15, 2024
I plan to make i32 an illegal type for RV64 to match SelectionDAG and to
remove i32 from the GPR register class.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants