[llvm] b41d22d - [PowerPC][GISel] support 32 bit load/store

Chen Zheng via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 12 04:53:54 PST 2022


Author: Chen Zheng
Date: 2022-12-12T12:52:44Z
New Revision: b41d22db18ec6f18a1a9e07d3581ee67164b2080

URL: https://github.com/llvm/llvm-project/commit/b41d22db18ec6f18a1a9e07d3581ee67164b2080
DIFF: https://github.com/llvm/llvm-project/commit/b41d22db18ec6f18a1a9e07d3581ee67164b2080.diff

LOG: [PowerPC][GISel] support 32 bit load/store

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D135535

Added: 
    llvm/test/CodeGen/PowerPC/GlobalISel/load-store-32bit.ll

Modified: 
    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/PPCGenRegisterBankInfo.def

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp b/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
index 172f403046c3..aeb33caaa3ed 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
@@ -52,6 +52,9 @@ class PPCInstructionSelector : public InstructionSelector {
   bool selectIntToFP(MachineInstr &I, MachineBasicBlock &MBB,
                   MachineRegisterInfo &MRI) const;
 
+  bool selectZExt(MachineInstr &I, MachineBasicBlock &MBB,
+                  MachineRegisterInfo &MRI) const;
+
   const PPCSubtarget &STI;
   const PPCInstrInfo &TII;
   const PPCRegisterInfo &TRI;
@@ -89,6 +92,8 @@ static const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank *RB) {
   if (RB->getID() == PPC::GPRRegBankID) {
     if (Ty.getSizeInBits() == 64)
       return &PPC::G8RCRegClass;
+    if (Ty.getSizeInBits() == 32)
+      return &PPC::GPRCRegClass;
   }
   if (RB->getID() == PPC::FPRRegBankID) {
     if (Ty.getSizeInBits() == 32)
@@ -130,6 +135,8 @@ static unsigned selectLoadStoreOp(unsigned GenericOpc, unsigned RegBankID,
   switch (RegBankID) {
   case PPC::GPRRegBankID:
     switch (OpSize) {
+    case 32:
+      return IsStore ? PPC::STW : PPC::LWZ;
     case 64:
       return IsStore ? PPC::STD : PPC::LD;
     default:
@@ -138,6 +145,8 @@ static unsigned selectLoadStoreOp(unsigned GenericOpc, unsigned RegBankID,
     break;
   case PPC::FPRRegBankID:
     switch (OpSize) {
+    case 32:
+      return IsStore ? PPC::STFS : PPC::LFS;
     case 64:
       return IsStore ? PPC::STFD : PPC::LFD;
     default:
@@ -207,6 +216,40 @@ bool PPCInstructionSelector::selectFPToInt(MachineInstr &I,
   return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
 }
 
+bool PPCInstructionSelector::selectZExt(MachineInstr &I, MachineBasicBlock &MBB,
+                                        MachineRegisterInfo &MRI) const {
+  const Register DstReg = I.getOperand(0).getReg();
+  const LLT DstTy = MRI.getType(DstReg);
+  const RegisterBank *DstRegBank = RBI.getRegBank(DstReg, MRI, TRI);
+
+  const Register SrcReg = I.getOperand(1).getReg();
+
+  assert(DstTy.getSizeInBits() == 64 && "Unexpected dest size!");
+  assert(MRI.getType(SrcReg).getSizeInBits() == 32 && "Unexpected src size!");
+
+  Register ImpDefReg =
+      MRI.createVirtualRegister(getRegClass(DstTy, DstRegBank));
+  BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::IMPLICIT_DEF),
+          ImpDefReg);
+
+  Register NewDefReg =
+      MRI.createVirtualRegister(getRegClass(DstTy, DstRegBank));
+  BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::INSERT_SUBREG),
+          NewDefReg)
+      .addReg(ImpDefReg)
+      .addReg(SrcReg)
+      .addImm(PPC::sub_32);
+
+  MachineInstr *MI =
+      BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), DstReg)
+          .addReg(NewDefReg)
+          .addImm(0)
+          .addImm(32);
+
+  I.eraseFromParent();
+  return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+}
+
 bool PPCInstructionSelector::select(MachineInstr &I) {
   auto &MBB = *I.getParent();
   auto &MF = *MBB.getParent();
@@ -270,6 +313,9 @@ bool PPCInstructionSelector::select(MachineInstr &I) {
   case TargetOpcode::G_FPTOSI:
   case TargetOpcode::G_FPTOUI:
     return selectFPToInt(I, MBB, MRI);
+  // G_SEXT will be selected in tb-gen pattern.
+  case TargetOpcode::G_ZEXT:
+    return selectZExt(I, MBB, MRI);
   }
   return false;
 }

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp b/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
index b47f7b942d09..0fb12ab4c658 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
@@ -20,11 +20,16 @@ using namespace LegalizeActions;
 PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) {
   using namespace TargetOpcode;
   const LLT P0 = LLT::pointer(0, 64);
+  const LLT S8 = LLT::scalar(8);
+  const LLT S16 = LLT::scalar(16);
   const LLT S32 = LLT::scalar(32);
   const LLT S64 = LLT::scalar(64);
   getActionDefinitionsBuilder(G_IMPLICIT_DEF).legalFor({S64});
   getActionDefinitionsBuilder(G_CONSTANT)
-      .legalFor({S64})
+      .legalFor({S32, S64})
+      .clampScalar(0, S64, S64);
+  getActionDefinitionsBuilder({G_ZEXT, G_SEXT})
+      .legalForCartesianProduct({S64}, {S8, S16, S32})
       .clampScalar(0, S64, S64);
   getActionDefinitionsBuilder({G_AND, G_OR, G_XOR})
       .legalFor({S64})
@@ -42,10 +47,8 @@ PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) {
   getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
       .legalForCartesianProduct({S32, S64}, {S64});
 
-  // For now only handle 64 bit, we only support 64 bit integer and zext/sext is
-  // not ready.
   getActionDefinitionsBuilder({G_LOAD, G_STORE})
-      .legalForTypesWithMemDesc({{S64, P0, S64, 8}});
+      .legalForTypesWithMemDesc({{S64, P0, S64, 8}, {S32, P0, S32, 4}});
 
   getLegacyLegalizerInfo().computeTables();
 }

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
index cd67dd9de9be..43abbd654653 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
@@ -35,6 +35,9 @@ PPCRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
   case PPC::G8RCRegClassID:
   case PPC::G8RC_NOX0RegClassID:
   case PPC::G8RC_and_G8RC_NOX0RegClassID:
+  case PPC::GPRCRegClassID:
+  case PPC::GPRC_NOR0RegClassID:
+  case PPC::GPRC_and_GPRC_NOR0RegClassID:
     return getRegBank(PPC::GPRRegBankID);
   case PPC::VSFRCRegClassID:
   case PPC::SPILLTOVSRRC_and_VSFRCRegClassID:
@@ -81,6 +84,9 @@ PPCRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
   case TargetOpcode::G_AND:
   case TargetOpcode::G_OR:
   case TargetOpcode::G_XOR:
+    // Extension ops.
+  case TargetOpcode::G_SEXT:
+  case TargetOpcode::G_ZEXT:
     assert(NumOperands <= 3 &&
            "This code is for instructions with 3 or less operands");
     OperandsMapping = getValueMapping(PMI_GPR64);
@@ -120,6 +126,7 @@ PPCRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
     break;
   }
   case TargetOpcode::G_LOAD: {
+    unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
     // Check if that load feeds fp instructions.
     if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
                [&](const MachineInstr &UseMI) {
@@ -133,21 +140,26 @@ PPCRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
                  return onlyUsesFP(UseMI, MRI, TRI);
                }))
       OperandsMapping = getOperandsMapping(
-          {getValueMapping(PMI_FPR64), getValueMapping(PMI_GPR64)});
+          {getValueMapping(Size == 64 ? PMI_FPR64 : PMI_FPR32),
+           getValueMapping(PMI_GPR64)});
     else
       OperandsMapping = getOperandsMapping(
-          {getValueMapping(PMI_GPR64), getValueMapping(PMI_GPR64)});
+          {getValueMapping(Size == 64 ? PMI_GPR64 : PMI_GPR32),
+           getValueMapping(PMI_GPR64)});
     break;
   }
   case TargetOpcode::G_STORE: {
     // Check if the store is fed by fp instructions.
     MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(0).getReg());
+    unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
     if (onlyDefinesFP(*DefMI, MRI, TRI))
       OperandsMapping = getOperandsMapping(
-          {getValueMapping(PMI_FPR64), getValueMapping(PMI_GPR64)});
+          {getValueMapping(Size == 64 ? PMI_FPR64 : PMI_FPR32),
+           getValueMapping(PMI_GPR64)});
     else
       OperandsMapping = getOperandsMapping(
-          {getValueMapping(PMI_GPR64), getValueMapping(PMI_GPR64)});
+          {getValueMapping(Size == 64 ? PMI_GPR64 : PMI_GPR32),
+           getValueMapping(PMI_GPR64)});
     break;
   }
   default:

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
index b1a16dbb60f6..f06a15affb40 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
+++ b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
@@ -28,10 +28,11 @@ class PPCGenRegisterBankInfo : public RegisterBankInfo {
 protected:
   enum PartialMappingIdx {
     PMI_None = -1,
-    PMI_GPR64 = 1,
-    PMI_FPR32 = 2,
-    PMI_FPR64 = 3,
-    PMI_Min = PMI_GPR64,
+    PMI_GPR32 = 1,
+    PMI_GPR64 = 2,
+    PMI_FPR32 = 3,
+    PMI_FPR64 = 4,
+    PMI_Min = PMI_GPR32,
   };
 
   static RegisterBankInfo::PartialMapping PartMappings[];

diff  --git a/llvm/lib/Target/PowerPC/PPCGenRegisterBankInfo.def b/llvm/lib/Target/PowerPC/PPCGenRegisterBankInfo.def
index f8c79fb3a1ca..897fe25bbe6c 100644
--- a/llvm/lib/Target/PowerPC/PPCGenRegisterBankInfo.def
+++ b/llvm/lib/Target/PowerPC/PPCGenRegisterBankInfo.def
@@ -14,11 +14,13 @@
 namespace llvm {
 RegisterBankInfo::PartialMapping PPCGenRegisterBankInfo::PartMappings[]{
     /* StartIdx, Length, RegBank */
-    // 0: GPR 64-bit value.
+    // 0: GPR 32-bit value.
+    {0, 32, PPC::GPRRegBank},
+    // 1: GPR 64-bit value.
     {0, 64, PPC::GPRRegBank},
-    // 1: FPR 32-bit value
+    // 2: FPR 32-bit value
     {0, 32, PPC::FPRRegBank},
-    // 2: FPR 64-bit value
+    // 3: FPR 64-bit value
     {0, 64, PPC::FPRRegBank},
 };
 
@@ -37,15 +39,19 @@ RegisterBankInfo::ValueMapping PPCGenRegisterBankInfo::ValMappings[]{
     /* BreakDown, NumBreakDowns */
     // 0: invalid
     {nullptr, 0},
-    // 1: GPR 64-bit value.
+    // 1: GPR 32-bit value.
+    {&PPCGenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
+    {&PPCGenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
+    {&PPCGenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
+    // 4: GPR 64-bit value.
     {&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.
+    // 7: 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.
+    // 10: 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},

diff  --git a/llvm/test/CodeGen/PowerPC/GlobalISel/load-store-32bit.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/load-store-32bit.ll
new file mode 100644
index 000000000000..0ecc24a834d8
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/GlobalISel/load-store-32bit.ll
@@ -0,0 +1,54 @@
+; 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 -verify-machineinstrs < %s | FileCheck %s
+
+define signext i32 @load_signext_i32(ptr %ptr) {
+; CHECK-LABEL: load_signext_i32:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lwa r3, 0(r3)
+; CHECK-NEXT:    blr
+entry:
+  %ret = load i32, ptr %ptr, align 4
+  ret i32 %ret
+}
+
+define zeroext i32 @load_zeroext_i32(ptr %ptr) {
+; CHECK-LABEL: load_zeroext_i32:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lwz r3, 0(r3)
+; CHECK-NEXT:    blr
+entry:
+  %ret = load i32, ptr %ptr, align 4
+  ret i32 %ret
+}
+
+define float @load_float(ptr %ptr) {
+; CHECK-LABEL: load_float:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lfs f1, 0(r3)
+; CHECK-NEXT:    blr
+entry:
+  %ret = load float, ptr %ptr, align 4
+  ret float %ret
+}
+
+define void @store_i32(ptr %p) {
+; CHECK-LABEL: store_i32:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    li r4, 100
+; CHECK-NEXT:    stw r4, 0(r3)
+; CHECK-NEXT:    blr
+entry:
+  store i32 100, ptr %p, align 4
+  ret void
+}
+
+define void @store_float(ptr %ptr, float %a) {
+; CHECK-LABEL: store_float:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    stfs f1, 0(r3)
+; CHECK-NEXT:    blr
+entry:
+  store float %a, ptr %ptr, align 4
+  ret void
+}


        


More information about the llvm-commits mailing list