diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 8905aa77dfcdd7..d745e0957168ce 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -139,10 +139,12 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) .clampScalar(1, sXLen, sXLen) .clampScalar(0, sXLen, sXLen); - getActionDefinitionsBuilder(G_SELECT) - .legalFor({{sXLen, sXLen}, {s32, sXLen}, {p0, sXLen}}) - .widenScalarToNextPow2(0) - .clampScalar(0, s32, sXLen) + auto &SelectActions = getActionDefinitionsBuilder(G_SELECT).legalFor( + {{s32, sXLen}, {p0, sXLen}}); + if (XLen == 64 || ST.hasStdExtD()) + SelectActions.legalFor({{s64, sXLen}}); + SelectActions.widenScalarToNextPow2(0) + .clampScalar(0, s32, (XLen == 64 || ST.hasStdExtD()) ? s64 : s32) .clampScalar(1, sXLen, sXLen); auto &LoadStoreActions = diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp index e28bd50b20d831..b8fafa154ca9ca 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp @@ -332,37 +332,42 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { // everything has to be on GPR. unsigned NumFP = 0; - // Check if the uses of the result always produce floating point values. - // - // For example: - // - // %z = G_SELECT %cond %x %y - // fpr = G_FOO %z ... - if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()), - [&](const MachineInstr &UseMI) { - return onlyUsesFP(UseMI, MRI, TRI); - })) - ++NumFP; - - // Check if the defs of the source values always produce floating point - // values. - // - // For example: - // - // %x = G_SOMETHING_ALWAYS_FLOAT %a ... - // %z = G_SELECT %cond %x %y - // - // Also check whether or not the sources have already been decided to be - // FPR. Keep track of this. - // - // This doesn't check the condition, since the condition is always an - // integer. - for (unsigned Idx = 2; Idx < 4; ++Idx) { - Register VReg = MI.getOperand(Idx).getReg(); - MachineInstr *DefMI = MRI.getVRegDef(VReg); - if (getRegBank(VReg, MRI, TRI) == &RISCV::FPRBRegBank || - onlyDefinesFP(*DefMI, MRI, TRI)) + // Use FPR64 for s64 select on rv32. + if (GPRSize == 32 && Ty.getSizeInBits() == 64) { + NumFP = 3; + } else { + // Check if the uses of the result always produce floating point values. + // + // For example: + // + // %z = G_SELECT %cond %x %y + // fpr = G_FOO %z ... + if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()), + [&](const MachineInstr &UseMI) { + return onlyUsesFP(UseMI, MRI, TRI); + })) ++NumFP; + + // Check if the defs of the source values always produce floating point + // values. + // + // For example: + // + // %x = G_SOMETHING_ALWAYS_FLOAT %a ... + // %z = G_SELECT %cond %x %y + // + // Also check whether or not the sources have already been decided to be + // FPR. Keep track of this. + // + // This doesn't check the condition, since the condition is always an + // integer. + for (unsigned Idx = 2; Idx < 4; ++Idx) { + Register VReg = MI.getOperand(Idx).getReg(); + MachineInstr *DefMI = MRI.getVRegDef(VReg); + if (getRegBank(VReg, MRI, TRI) == &RISCV::FPRBRegBank || + onlyDefinesFP(*DefMI, MRI, TRI)) + ++NumFP; + } } // Condition operand is always GPR. diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv32.mir index 4fffbc42b2cff3..9d898c431e16b3 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv32.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv32.mir @@ -31,3 +31,32 @@ body: | PseudoRET implicit $f10_f ... +--- +name: fp_select_s64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $f10_d, $f11_d + + ; CHECK-LABEL: name: fp_select_s64 + ; CHECK: liveins: $x10, $f10_d, $f11_d + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $f10_d + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY $f11_d + ; CHECK-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY]], 1 + ; CHECK-NEXT: [[Select_FPR64_Using_CC_GPR:%[0-9]+]]:fpr64 = Select_FPR64_Using_CC_GPR [[ANDI]], $x0, 1, [[COPY1]], [[COPY2]] + ; CHECK-NEXT: $f10_d = COPY [[Select_FPR64_Using_CC_GPR]] + ; CHECK-NEXT: PseudoRET implicit $f10_d + %0:gprb(s32) = COPY $x10 + %1:fprb(s64) = COPY $f10_d + %2:fprb(s64) = COPY $f11_d + %3:gprb(s32) = G_CONSTANT i32 1 + %4:gprb(s32) = G_AND %0, %3 + %5:fprb(s64) = G_SELECT %4(s32), %1, %2 + $f10_d = COPY %5(s64) + PseudoRET implicit $f10_d + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fp-select-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fp-select-rv32.mir new file mode 100644 index 00000000000000..487608f33b64bc --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fp-select-rv32.mir @@ -0,0 +1,31 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4 +# RUN: llc -mtriple=riscv32 -mattr=+d -run-pass=legalizer %s -o - \ +# RUN: | FileCheck %s + +--- +name: select_f64 +tracksRegLiveness: true +body: | + bb.1: + liveins: $x10, $f10_d, $f11_d + + ; CHECK-LABEL: name: select_f64 + ; CHECK: liveins: $x10, $f10_d, $f11_d + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f10_d + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f11_d + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]] + ; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s64) = G_SELECT [[AND]](s32), [[COPY1]], [[COPY2]] + ; CHECK-NEXT: $f10_d = COPY [[SELECT]](s64) + ; CHECK-NEXT: PseudoRET implicit $f10_d + %3:_(s32) = COPY $x10 + %0:_(s1) = G_TRUNC %3(s32) + %1:_(s64) = COPY $f10_d + %2:_(s64) = COPY $f11_d + %4:_(s64) = G_SELECT %0(s1), %1, %2 + $f10_d = COPY %4(s64) + PseudoRET implicit $f10_d + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv32.mir index 6d8ca3eb6d8271..835f026d187a24 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv32.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv32.mir @@ -31,6 +31,35 @@ body: | $f10_f = COPY %10(s32) PseudoRET implicit $f10_f +... +--- +name: fp_select_s64 +legalized: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $f10_d, $f11_d + + ; RV32I-LABEL: name: fp_select_s64 + ; RV32I: liveins: $x10, $f10_d, $f11_d + ; RV32I-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s64) = COPY $f10_d + ; RV32I-NEXT: [[COPY2:%[0-9]+]]:fprb(s64) = COPY $f11_d + ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1 + ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY]], [[C]] + ; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s64) = G_SELECT [[AND]](s32), [[COPY1]], [[COPY2]] + ; RV32I-NEXT: $f10_d = COPY [[SELECT]](s64) + ; RV32I-NEXT: PseudoRET implicit $f10_d + %3:_(s32) = COPY $x10 + %4:_(s64) = COPY $f10_d + %5:_(s64) = COPY $f11_d + %12:_(s32) = G_CONSTANT i32 1 + %11:_(s32) = G_AND %3, %12 + %10:_(s64) = G_SELECT %11(s32), %4, %5 + $f10_d = COPY %10(s64) + PseudoRET implicit $f10_d + ... --- name: fp_select_gpr_use_s32