-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
Conversation
@llvm/pr-subscribers-backend-risc-v Author: Craig Topper (topperc) ChangesI 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:
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]
|
@llvm/pr-subscribers-llvm-globalisel Author: Craig Topper (topperc) ChangesI 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:
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]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
e0b7bf0
to
f8af6d7
Compare
I plan to make i32 an illegal type for RV64 to match SelectionDAG and to remove i32 from the GPR register class.
I plan to make i32 an illegal type for RV64 to match SelectionDAG and to remove i32 from the GPR register class.