[llvm-branch-commits] [llvm] 13e5c76 - Kai's GISEL Patch 3
Amy Kwan via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Sep 2 09:09:25 PDT 2022
Author: Amy Kwan
Date: 2022-08-30T15:04:50-05:00
New Revision: 13e5c764a2e88d866d679cc73927648afaafd48e
URL: https://github.com/llvm/llvm-project/commit/13e5c764a2e88d866d679cc73927648afaafd48e
DIFF: https://github.com/llvm/llvm-project/commit/13e5c764a2e88d866d679cc73927648afaafd48e.diff
LOG: Kai's GISEL Patch 3
Added:
llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-constant.ll
Modified:
llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-logical.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp b/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
index b461ca4a28e1..f44a22308496 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
@@ -43,6 +43,11 @@ class PPCInstructionSelector : public InstructionSelector {
/// selector for the patterns that do not require complex C++.
bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
+ bool selectConst(MachineInstr &I, MachineBasicBlock &MBB,
+ MachineRegisterInfo &MRI) const;
+ bool selectSExt(MachineInstr &I, MachineBasicBlock &MBB,
+ MachineRegisterInfo &MRI) const;
+
const PPCInstrInfo &TII;
const PPCRegisterInfo &TRI;
const PPCRegisterBankInfo &RBI;
@@ -91,6 +96,102 @@ static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
return true;
}
+bool PPCInstructionSelector::selectConst(MachineInstr &I,
+ MachineBasicBlock &MBB,
+ MachineRegisterInfo &MRI) const {
+ assert(I.getOpcode() == TargetOpcode::G_CONSTANT && "Unexpected G code");
+
+ MachineInstr *MI = nullptr;
+ Register DstReg = I.getOperand(0).getReg();
+ APInt ConstValue = I.getOperand(1).getCImm()->getValue();
+ if (ConstValue.isIntN(16)) {
+ bool NeedMask = !ConstValue.isIntN(15);
+ uint64_t Cst = ConstValue.getZExtValue();
+ Register TmpReg =
+ NeedMask ? MRI.createVirtualRegister(&PPC::G8RCRegClass) : DstReg;
+ MI =
+ BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg).addImm(Cst);
+ if (NeedMask) {
+ constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+ MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDIC), DstReg)
+ .addReg(TmpReg, RegState::Kill)
+ .addImm(0)
+ .addImm(16);
+ }
+ } else if (ConstValue.isSignedIntN(16)) {
+ int64_t Cst = ConstValue.getSExtValue();
+ MI =
+ BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), DstReg).addImm(Cst);
+ } else if (ConstValue.isSignedIntN(32)) {
+ int64_t Cst = ConstValue.getSExtValue();
+ int64_t UpperCst = Cst >> 16;
+ int64_t LowerCst = Cst & 0xffff;
+ Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
+ MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LIS8), TmpReg)
+ .addImm(UpperCst);
+ constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+ MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), DstReg)
+ .addReg(TmpReg, RegState::Kill)
+ .addImm(LowerCst);
+ } else if (ConstValue.isIntN(32)) {
+ bool NeedMask = !ConstValue.isIntN(31);
+ uint64_t Cst = ConstValue.getZExtValue();
+ uint64_t UpperCst = Cst >> 16;
+ uint64_t LowerCst = Cst & 0xffff;
+ Register TmpReg =
+ NeedMask ? MRI.createVirtualRegister(&PPC::G8RCRegClass) : DstReg;
+ if (UpperCst == 0xffff && (LowerCst & 0x8000) == 0x8000) {
+ MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
+ .addImm(LowerCst);
+ } else {
+ Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
+ MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LIS8), Tmp2Reg)
+ .addImm(UpperCst);
+ constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+ MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), TmpReg)
+ .addReg(Tmp2Reg, RegState::Kill)
+ .addImm(LowerCst);
+ }
+ if (NeedMask) {
+ constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+ MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDIC), DstReg)
+ .addReg(TmpReg, RegState::Kill)
+ .addImm(0)
+ .addImm(32);
+ }
+ } else
+ return false;
+ I.eraseFromParent();
+ return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+}
+
+bool PPCInstructionSelector::selectSExt(MachineInstr &I, MachineBasicBlock &MBB,
+ MachineRegisterInfo &MRI) const {
+ assert(I.getOpcode() == TargetOpcode::G_SEXT_INREG && "Unexpected G code");
+
+ Register DstReg = I.getOperand(0).getReg();
+ Register SrcReg = I.getOperand(1).getReg();
+
+ unsigned Opc;
+ switch (I.getOperand(2).getImm()) {
+ case 8:
+ Opc = PPC::EXTSB8;
+ break;
+ case 16:
+ Opc = PPC::EXTSH8;
+ break;
+ case 32:
+ Opc = PPC::EXTSW;
+ break;
+ default:
+ return false;
+ }
+ MachineInstr *MI =
+ BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opc), DstReg).addReg(SrcReg);
+ I.eraseFromParent();
+ return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+}
+
bool PPCInstructionSelector::select(MachineInstr &I) {
auto &MBB = *I.getParent();
auto &MF = *MBB.getParent();
@@ -105,7 +206,15 @@ bool PPCInstructionSelector::select(MachineInstr &I) {
if (selectImpl(I, *CoverageInfo))
return true;
- return false;
+
+ switch (I.getOpcode()) {
+ case TargetOpcode::G_CONSTANT:
+ return selectConst(I, MBB, MRI);
+ case TargetOpcode::G_SEXT_INREG:
+ return selectSExt(I, MBB, MRI);
+ default:
+ return false;
+ }
}
namespace llvm {
diff --git a/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp b/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
index bbbd211269d4..903ccb4dcd80 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
@@ -19,11 +19,21 @@ using namespace LegalizeActions;
PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) {
using namespace TargetOpcode;
+ 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})
.clampScalar(0, S64, S64);
+ getActionDefinitionsBuilder(G_TRUNC)
+ .legalForCartesianProduct({S8, S16, S32}, {S64});
+ getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
+ .legalForCartesianProduct({S64}, {S8, S16, S32})
+ .clampScalar(0, S64, S64);
+ getActionDefinitionsBuilder(G_SEXT_INREG)
+ .legalForTypeWithAnyImm({S64});
getActionDefinitionsBuilder({G_AND, G_OR, G_XOR})
.legalFor({S64})
.clampScalar(0, S64, S64);
diff --git a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
index f1732742438e..575d4d4d125a 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
@@ -35,6 +35,8 @@ PPCRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
case PPC::G8RCRegClassID:
case PPC::G8RC_NOX0RegClassID:
case PPC::G8RC_and_G8RC_NOX0RegClassID:
+ case PPC::G8pRCRegClassID:
+ case PPC::G8pRC_with_sub_32_in_GPRC_NOR0RegClassID:
return getRegBank(PPC::GPRRegBankID);
default:
llvm_unreachable("Unexpected register class");
@@ -73,10 +75,19 @@ PPCRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case TargetOpcode::G_AND:
case TargetOpcode::G_OR:
case TargetOpcode::G_XOR:
+ // Truncation & extension ops.
+ case TargetOpcode::G_SEXT:
+ case TargetOpcode::G_ZEXT:
+ case TargetOpcode::G_ANYEXT:
+ case TargetOpcode::G_TRUNC:
assert(NumOperands <= 3 &&
"This code is for instructions with 3 or less operands");
OperandsMapping = getValueMapping(PMI_GPR64);
break;
+ case TargetOpcode::G_SEXT_INREG:
+ OperandsMapping = getOperandsMapping(
+ {getValueMapping(PMI_GPR64), getValueMapping(PMI_GPR64), nullptr});
+ break;
case TargetOpcode::G_CONSTANT:
OperandsMapping = getOperandsMapping({getValueMapping(PMI_GPR64), nullptr});
break;
diff --git a/llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-constant.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-constant.ll
new file mode 100644
index 000000000000..f1651af98840
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-constant.ll
@@ -0,0 +1,54 @@
+; RUN: llc -mtriple ppc64le-linux -global-isel -o - < %s | FileCheck %s -check-prefixes=CHECK,LINUX
+
+; CHECK-LABEL: f1:
+; LINUX: li 3, 1
+; LINUX: blr
+define zeroext i32 @f1() {
+ ret i32 1
+}
+
+; CHECK-LABEL: f2:
+; LINUX: li 3, -1
+; LINUX: rldic 3, 3, 0, 32
+; LINUX: blr
+define zeroext i32 @f2() {
+ ret i32 -1
+}
+
+; CHECK-LABEL: f3:
+; LINUX: li 3, 1
+; LINUX: blr
+define signext i32 @f3() {
+ ret i32 1
+}
+
+; CHECK-LABEL: f4:
+; LINUX: li 3, -1
+; LINUX: blr
+define signext i32 @f4() {
+ ret i32 -1
+}
+
+; CHECK-LABEL: f5:
+; LINUX: li 3, -52
+; LINUX: blr
+define signext i32 @f5() {
+ ret i32 -52
+}
+
+; CHECK-LABEL: f6:
+; LINUX: li 3, -13142
+; LINUX: rldic 3, 3, 0, 16
+; LINUX: blr
+define zeroext i32 @f6() {
+ ret i32 52394
+}
+
+; CHECK-LABEL: f7:
+; LINUX: lis 3, -18
+; LINUX: ori 3, 3, 56780
+; LINUX: rldic 3, 3, 0, 32
+; LINUX: blr
+define zeroext i32 @f7() {
+ ret i32 4293844428
+}
diff --git a/llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-logical.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-logical.ll
index 09ccc80581e5..d808e6d5f78d 100644
--- a/llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-logical.ll
+++ b/llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-logical.ll
@@ -8,6 +8,65 @@ define i64 @test_andi64(i64 %a, i64 %b) {
ret i64 %res
}
+; CHECK-LABEL: test_andui32:
+; LINUX: li 5, -1
+; LINUX: and 3, 3, 4
+; LINUX: rldic 4, 5, 0, 32
+; LINUX: and 3, 3, 4
+; LINUX: blr
+define zeroext i32 @test_andui32(i32 zeroext %a, i32 zeroext %b) {
+ %res = and i32 %a, %b
+ ret i32 %res
+}
+
+; CHECK-LABEL: test_andsi32:
+; LINUX: and 3, 3, 4
+; LINUX: extsw 3, 3
+; LINUX: blr
+define signext i32 @test_andsi32(i32 signext %a, i32 signext %b) {
+ %res = and i32 %a, %b
+ ret i32 %res
+}
+
+; CHECK-LABEL: test_andui16:
+; LINUX: li 5, -1
+; LINUX: and 3, 3, 4
+; LINUX: rldic 4, 5, 0, 16
+; LINUX: and 3, 3, 4
+; LINUX: blr
+define zeroext i16 @test_andui16(i16 zeroext %a, i16 zeroext %b) {
+ %res = and i16 %a, %b
+ ret i16 %res
+}
+
+; CHECK-LABEL: test_andsi16:
+; LINUX: and 3, 3, 4
+; LINUX: extsh 3, 3
+; LINUX: blr
+define signext i16 @test_andsi16(i16 signext %a, i16 signext %b) {
+ %res = and i16 %a, %b
+ ret i16 %res
+}
+
+; CHECK-LABEL: test_andui8:
+; LINUX: li 5, 255
+; LINUX: and 3, 3, 4
+; LINUX: and 3, 3, 5
+; LINUX: blr
+define zeroext i8 @test_andui8(i8 zeroext %a, i8 zeroext %b) {
+ %res = and i8 %a, %b
+ ret i8 %res
+}
+
+; CHECK-LABEL: test_andsi8:
+; LINUX: and 3, 3, 4
+; LINUX: extsb 3, 3
+; LINUX: blr
+define signext i8 @test_andsi8(i8 signext %a, i8 signext %b) {
+ %res = and i8 %a, %b
+ ret i8 %res
+}
+
; CHECK-LABEL: test_nandi64:
; LINUX: nand 3, 3, 4
; LINUX: blr
More information about the llvm-branch-commits
mailing list