Add global isel support for G_FADD, G_FSUB, G_FMUL, G_FDIV.
Reviewed By: Kai, nemanjai, arsenm, amyk
Differential Revision: https://reviews.llvm.org/D132942
if (Ty.getSizeInBits() == 64)
return &PPC::G8RCRegClass;
}
+ if (RB->getID() == PPC::FPRRegBankID) {
+ if (Ty.getSizeInBits() == 32)
+ return &PPC::F4RCRegClass;
+ if (Ty.getSizeInBits() == 64)
+ return &PPC::F8RCRegClass;
+ }
llvm_unreachable("Unknown RegBank!");
}
PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) {
using namespace TargetOpcode;
+ const LLT S32 = LLT::scalar(32);
const LLT S64 = LLT::scalar(64);
getActionDefinitionsBuilder(G_IMPLICIT_DEF).legalFor({S64});
getActionDefinitionsBuilder(G_CONSTANT)
getActionDefinitionsBuilder({G_ADD, G_SUB})
.legalFor({S64})
.clampScalar(0, S64, S64);
+
+ getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV})
+ .legalFor({S32, S64});
+
getLegacyLegalizerInfo().computeTables();
}
case PPC::G8RC_NOX0RegClassID:
case PPC::G8RC_and_G8RC_NOX0RegClassID:
return getRegBank(PPC::GPRRegBankID);
+ case PPC::VSFRCRegClassID:
+ case PPC::SPILLTOVSRRC_and_VSFRCRegClassID:
+ case PPC::SPILLTOVSRRC_and_VFRCRegClassID:
+ case PPC::SPILLTOVSRRC_and_F4RCRegClassID:
+ case PPC::F8RCRegClassID:
+ case PPC::VFRCRegClassID:
+ case PPC::VSSRCRegClassID:
+ case PPC::F4RCRegClassID:
+ return getRegBank(PPC::FPRRegBankID);
default:
llvm_unreachable("Unexpected register class");
}
return Mapping;
}
+ const MachineFunction &MF = *MI.getParent()->getParent();
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
+ const TargetSubtargetInfo &STI = MF.getSubtarget();
+ const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
+
unsigned NumOperands = MI.getNumOperands();
const ValueMapping *OperandsMapping = nullptr;
unsigned Cost = 1;
"This code is for instructions with 3 or less operands");
OperandsMapping = getValueMapping(PMI_GPR64);
break;
+ case TargetOpcode::G_FADD:
+ case TargetOpcode::G_FSUB:
+ case TargetOpcode::G_FMUL:
+ case TargetOpcode::G_FDIV: {
+ Register SrcReg = MI.getOperand(1).getReg();
+ unsigned Size = getSizeInBits(SrcReg, MRI, TRI);
+
+ assert((Size == 32 || Size == 64) && "Unsupported floating point types!\n");
+ OperandsMapping = getValueMapping(Size == 32 ? PMI_FPR32 : PMI_FPR64);
+ break;
+ }
case TargetOpcode::G_CONSTANT:
OperandsMapping = getOperandsMapping({getValueMapping(PMI_GPR64), nullptr});
break;
enum PartialMappingIdx {
PMI_None = -1,
PMI_GPR64 = 1,
+ PMI_FPR32 = 2,
+ PMI_FPR64 = 3,
PMI_Min = PMI_GPR64,
};
/// General Purpose Registers
def GPRRegBank : RegisterBank<"GPR", [G8RC, G8RC_NOX0]>;
+/// Floating point Registers
+def FPRRegBank : RegisterBank<"FPR", [VSSRC]>;
/* StartIdx, Length, RegBank */
// 0: GPR 64-bit value.
{0, 64, PPC::GPRRegBank},
+ // 1: FPR 32-bit value
+ {0, 32, PPC::FPRRegBank},
+ // 2: FPR 64-bit value
+ {0, 64, PPC::FPRRegBank},
};
// ValueMappings.
{&PPCGenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
{&PPCGenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
{&PPCGenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
+ // 4: FPR 32-bit value.
+ {&PPCGenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
+ {&PPCGenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
+ {&PPCGenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
+ // 7: FPR 64-bit value.
+ {&PPCGenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
+ {&PPCGenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
+ {&PPCGenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
};
// TODO Too simple!
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -global-isel -o - \
+; RUN: -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names < %s | FileCheck %s
+
+define float @float_add(float %a, float %b) {
+; CHECK-LABEL: float_add:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xsaddsp f1, f1, f2
+; CHECK-NEXT: blr
+entry:
+ %add = fadd float %a, %b
+ ret float %add
+}
+
+define double @double_add(double %a, double %b) {
+; CHECK-LABEL: double_add:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xsadddp f1, f1, f2
+; CHECK-NEXT: blr
+entry:
+ %add = fadd double %a, %b
+ ret double %add
+}
+
+define float @float_sub(float %a, float %b) {
+; CHECK-LABEL: float_sub:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xssubsp f1, f1, f2
+; CHECK-NEXT: blr
+entry:
+ %sub = fsub float %a, %b
+ ret float %sub
+}
+
+define float @float_mul(float %a, float %b) {
+; CHECK-LABEL: float_mul:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xsmulsp f1, f1, f2
+; CHECK-NEXT: blr
+entry:
+ %mul = fmul float %a, %b
+ ret float %mul
+}
+
+define float @float_div(float %a, float %b) {
+; CHECK-LABEL: float_div:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xsdivsp f1, f1, f2
+; CHECK-NEXT: blr
+entry:
+ %div = fdiv float %a, %b
+ ret float %div
+}