Skip to content

Commit

Permalink
[PowerPC][GISel] support 32 bit load/store
Browse files Browse the repository at this point in the history
Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D135535
  • Loading branch information
chenzheng1030 committed Dec 12, 2022
1 parent 7d5bef7 commit b41d22d
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 18 deletions.
46 changes: 46 additions & 0 deletions llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;
}
Expand Down
11 changes: 7 additions & 4 deletions llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
Expand Up @@ -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})
Expand All @@ -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();
}
20 changes: 16 additions & 4 deletions llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
Expand Up @@ -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:
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -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:
Expand Down
9 changes: 5 additions & 4 deletions llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
Expand Up @@ -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[];
Expand Down
18 changes: 12 additions & 6 deletions llvm/lib/Target/PowerPC/PPCGenRegisterBankInfo.def
Expand Up @@ -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},
};

Expand All @@ -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},
Expand Down
54 changes: 54 additions & 0 deletions 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
}

0 comments on commit b41d22d

Please sign in to comment.