[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