[PowerPC][GISel]add support for float point arithmetic operations
authorChen Zheng <czhengsz@cn.ibm.com>
Tue, 22 Nov 2022 07:40:30 +0000 (02:40 -0500)
committerChen Zheng <czhengsz@cn.ibm.com>
Tue, 22 Nov 2022 08:00:27 +0000 (03:00 -0500)
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

llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
llvm/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
llvm/lib/Target/PowerPC/PPCGenRegisterBankInfo.def
llvm/test/CodeGen/PowerPC/GlobalISel/float-arithmetic.ll [new file with mode: 0644]

index 93bbb9c..d3e3fb1 100644 (file)
@@ -80,6 +80,12 @@ static const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank *RB) {
     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!");
 }
index bbbd211..86dd11d 100644 (file)
@@ -19,6 +19,7 @@ using namespace LegalizeActions;
 
 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)
@@ -30,5 +31,9 @@ PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) {
   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();
 }
index 8a57010..4f31229 100644 (file)
@@ -36,6 +36,15 @@ PPCRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
   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");
   }
@@ -54,6 +63,11 @@ PPCRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
       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;
@@ -71,6 +85,17 @@ PPCRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
            "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;
index 11bdd98..40959a3 100644 (file)
@@ -29,6 +29,8 @@ protected:
   enum PartialMappingIdx {
     PMI_None = -1,
     PMI_GPR64 = 1,
+    PMI_FPR32 = 2,
+    PMI_FPR64 = 3,
     PMI_Min = PMI_GPR64,
   };
 
index 771d33e..b5f39e4 100644 (file)
@@ -13,3 +13,5 @@
 
 /// General Purpose Registers
 def GPRRegBank : RegisterBank<"GPR", [G8RC, G8RC_NOX0]>;
+/// Floating point Registers
+def FPRRegBank : RegisterBank<"FPR", [VSSRC]>;
index 471af5d..f8c79fb 100644 (file)
@@ -16,6 +16,10 @@ RegisterBankInfo::PartialMapping PPCGenRegisterBankInfo::PartMappings[]{
     /* 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.
@@ -37,6 +41,14 @@ RegisterBankInfo::ValueMapping PPCGenRegisterBankInfo::ValMappings[]{
     {&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!
diff --git a/llvm/test/CodeGen/PowerPC/GlobalISel/float-arithmetic.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/float-arithmetic.ll
new file mode 100644 (file)
index 0000000..185fa4d
--- /dev/null
@@ -0,0 +1,53 @@
+; 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
+}