forked from OSchip/llvm-project
AMDGPU/GlobalISel: Define InstrMappings for G_ICMP
Patch by Tom Stellard llvm-svn: 326472
This commit is contained in:
parent
dc14ec05d4
commit
50721ab325
|
@ -19,7 +19,9 @@ enum PartialMappingIdx {
|
|||
PM_SGPR32 = 0,
|
||||
PM_SGPR64 = 1,
|
||||
PM_VGPR32 = 2,
|
||||
PM_VGPR64 = 3
|
||||
PM_VGPR64 = 3,
|
||||
PM_SGPR1 = 4,
|
||||
PM_VGPR1 = 5,
|
||||
};
|
||||
|
||||
const RegisterBankInfo::PartialMapping PartMappings[] {
|
||||
|
@ -27,7 +29,9 @@ const RegisterBankInfo::PartialMapping PartMappings[] {
|
|||
{0, 32, SGPRRegBank},
|
||||
{0, 64, SGPRRegBank},
|
||||
{0, 32, VGPRRegBank},
|
||||
{0, 64, VGPRRegBank}
|
||||
{0, 64, VGPRRegBank},
|
||||
{0, 1, SCCRegBank},
|
||||
{0, 1, SGPRRegBank}
|
||||
};
|
||||
|
||||
const RegisterBankInfo::ValueMapping ValMappings[] {
|
||||
|
@ -38,7 +42,9 @@ const RegisterBankInfo::ValueMapping ValMappings[] {
|
|||
// VGPR 32-bit
|
||||
{&PartMappings[2], 1},
|
||||
// VGPR 64-bit
|
||||
{&PartMappings[3], 1}
|
||||
{&PartMappings[3], 1},
|
||||
{&PartMappings[4], 1},
|
||||
{&PartMappings[5], 1}
|
||||
};
|
||||
|
||||
enum ValueMappingIdx {
|
||||
|
@ -48,9 +54,14 @@ enum ValueMappingIdx {
|
|||
|
||||
const RegisterBankInfo::ValueMapping *getValueMapping(unsigned BankID,
|
||||
unsigned Size) {
|
||||
assert(Size % 32 == 0);
|
||||
unsigned Idx = BankID == AMDGPU::SGPRRegBankID ? SGPRStartIdx : VGPRStartIdx;
|
||||
Idx += (Size / 32) - 1;
|
||||
unsigned Idx;
|
||||
if (Size == 1) {
|
||||
Idx = BankID == AMDGPU::SCCRegBankID ? PM_SGPR1 : PM_VGPR1;
|
||||
} else {
|
||||
assert(Size % 32 == 0);
|
||||
Idx = BankID == AMDGPU::SGPRRegBankID ? SGPRStartIdx : VGPRStartIdx;
|
||||
Idx += (Size / 32) - 1;
|
||||
}
|
||||
return &ValMappings[Idx];
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,13 @@ unsigned AMDGPURegisterBankInfo::copyCost(const RegisterBank &Dst,
|
|||
if (Dst.getID() == AMDGPU::SGPRRegBankID &&
|
||||
Src.getID() == AMDGPU::VGPRRegBankID)
|
||||
return std::numeric_limits<unsigned>::max();
|
||||
|
||||
// SGPRRegBank with size 1 is actually vcc or another 64-bit sgpr written by
|
||||
// the valu.
|
||||
if (Size == 1 && Dst.getID() == AMDGPU::SCCRegBankID &&
|
||||
Src.getID() == AMDGPU::SGPRRegBankID)
|
||||
return std::numeric_limits<unsigned>::max();
|
||||
|
||||
return RegisterBankInfo::copyCost(Dst, Src, Size);
|
||||
}
|
||||
|
||||
|
@ -75,11 +82,11 @@ AMDGPURegisterBankInfo::getInstrAlternativeMappings(
|
|||
const MachineFunction &MF = *MI.getParent()->getParent();
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
|
||||
unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
|
||||
|
||||
InstructionMappings AltMappings;
|
||||
switch (MI.getOpcode()) {
|
||||
case TargetOpcode::G_LOAD: {
|
||||
unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
|
||||
// FIXME: Should we be hard coding the size for these mappings?
|
||||
const InstructionMapping &SSMapping = getInstructionMapping(
|
||||
1, 1, getOperandsMapping(
|
||||
|
@ -107,6 +114,42 @@ AMDGPURegisterBankInfo::getInstrAlternativeMappings(
|
|||
return AltMappings;
|
||||
|
||||
}
|
||||
case TargetOpcode::G_ICMP: {
|
||||
unsigned Size = getSizeInBits(MI.getOperand(2).getReg(), MRI, *TRI);
|
||||
const InstructionMapping &SSMapping = getInstructionMapping(1, 1,
|
||||
getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SCCRegBankID, 1),
|
||||
nullptr, // Predicate operand.
|
||||
AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
|
||||
AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
|
||||
4); // Num Operands
|
||||
AltMappings.push_back(&SSMapping);
|
||||
|
||||
const InstructionMapping &SVMapping = getInstructionMapping(2, 1,
|
||||
getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
|
||||
nullptr, // Predicate operand.
|
||||
AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
|
||||
AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
|
||||
4); // Num Operands
|
||||
AltMappings.push_back(&SVMapping);
|
||||
|
||||
const InstructionMapping &VSMapping = getInstructionMapping(3, 1,
|
||||
getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
|
||||
nullptr, // Predicate operand.
|
||||
AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
|
||||
AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}),
|
||||
4); // Num Operands
|
||||
AltMappings.push_back(&VSMapping);
|
||||
|
||||
const InstructionMapping &VVMapping = getInstructionMapping(4, 1,
|
||||
getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1),
|
||||
nullptr, // Predicate operand.
|
||||
AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
|
||||
AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}),
|
||||
4); // Num Operands
|
||||
AltMappings.push_back(&VVMapping);
|
||||
|
||||
return AltMappings;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -158,6 +201,22 @@ AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const {
|
|||
// handle that during instruction selection?
|
||||
}
|
||||
|
||||
unsigned
|
||||
AMDGPURegisterBankInfo::getRegBankID(unsigned Reg,
|
||||
const MachineRegisterInfo &MRI,
|
||||
const TargetRegisterInfo &TRI,
|
||||
unsigned Default) const {
|
||||
|
||||
const RegisterBank *Bank = getRegBank(Reg, MRI, TRI);
|
||||
return Bank ? Bank->getID() : Default;
|
||||
}
|
||||
|
||||
///
|
||||
/// This function must return a legal mapping, because
|
||||
/// AMDGPURegisterBankInfo::getInstrAlternativeMappings() is not called
|
||||
/// in RegBankSelect::Mode::Fast. Any mapping that would cause a
|
||||
/// VGPR to SGPR generated is illegal.
|
||||
///
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
|
||||
|
@ -213,6 +272,20 @@ AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
|||
break;
|
||||
}
|
||||
|
||||
case AMDGPU::G_ICMP: {
|
||||
unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
|
||||
unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI);
|
||||
unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI, *TRI);
|
||||
unsigned Op0Bank = Op2Bank == AMDGPU::SGPRRegBankID &&
|
||||
Op3Bank == AMDGPU::SGPRRegBankID ?
|
||||
AMDGPU::SCCRegBankID : AMDGPU::VGPRRegBankID;
|
||||
OpdsMapping[0] = AMDGPU::getValueMapping(Op0Bank, 1);
|
||||
OpdsMapping[1] = nullptr; // Predicate Operand.
|
||||
OpdsMapping[2] = AMDGPU::getValueMapping(Op2Bank, Size);
|
||||
OpdsMapping[3] = AMDGPU::getValueMapping(Op3Bank, Size);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMDGPU::G_LOAD:
|
||||
return getInstrMappingForLoad(MI);
|
||||
}
|
||||
|
|
|
@ -16,19 +16,15 @@
|
|||
|
||||
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
|
||||
|
||||
#define GET_REGBANK_DECLARATIONS
|
||||
#include "AMDGPUGenRegisterBank.inc"
|
||||
#undef GET_REGBANK_DECLARATIONS
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class SIRegisterInfo;
|
||||
class TargetRegisterInfo;
|
||||
|
||||
namespace AMDGPU {
|
||||
enum {
|
||||
SGPRRegBankID = 0,
|
||||
VGPRRegBankID = 1,
|
||||
NumRegisterBanks
|
||||
};
|
||||
} // End AMDGPU namespace.
|
||||
|
||||
/// This class provides the information for the target register banks.
|
||||
class AMDGPUGenRegisterBankInfo : public RegisterBankInfo {
|
||||
|
||||
|
@ -46,6 +42,10 @@ class AMDGPURegisterBankInfo : public AMDGPUGenRegisterBankInfo {
|
|||
const RegisterBankInfo::InstructionMapping &
|
||||
getInstrMappingForLoad(const MachineInstr &MI) const;
|
||||
|
||||
unsigned getRegBankID(unsigned Reg, const MachineRegisterInfo &MRI,
|
||||
const TargetRegisterInfo &TRI,
|
||||
unsigned Default = AMDGPU::VGPRRegBankID) const;
|
||||
|
||||
public:
|
||||
AMDGPURegisterBankInfo(const TargetRegisterInfo &TRI);
|
||||
|
||||
|
|
|
@ -14,3 +14,5 @@ def SGPRRegBank : RegisterBank<"SGPR",
|
|||
def VGPRRegBank : RegisterBank<"VGPR",
|
||||
[VGPR_32, VReg_64, VReg_96, VReg_128, VReg_256, VReg_512]
|
||||
>;
|
||||
|
||||
def SCCRegBank : RegisterBank <"SCC", [SCC_CLASS ]>;
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||
# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=regbankselect -global-isel %s -verify-machineinstrs -o - -regbankselect-fast | FileCheck %s
|
||||
# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=regbankselect -global-isel %s -verify-machineinstrs -o - -regbankselect-greedy | FileCheck %s
|
||||
|
||||
---
|
||||
name: icmp_ss
|
||||
legalized: true
|
||||
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $sgpr0, $sgpr1
|
||||
; CHECK-LABEL: name: icmp_ss
|
||||
; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0
|
||||
; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr1
|
||||
; CHECK: [[ICMP:%[0-9]+]]:scc(s1) = G_ICMP intpred(ne), [[COPY]](s32), [[COPY1]]
|
||||
%0:_(s32) = COPY $sgpr0
|
||||
%1:_(s32) = COPY $sgpr1
|
||||
%2:_(s1) = G_ICMP intpred(ne), %0, %1
|
||||
...
|
||||
|
||||
---
|
||||
name: icmp_sv
|
||||
legalized: true
|
||||
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $sgpr0, $vgpr0
|
||||
; CHECK-LABEL: name: icmp_sv
|
||||
; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0
|
||||
; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
|
||||
; CHECK: [[ICMP:%[0-9]+]]:sgpr(s1) = G_ICMP intpred(ne), [[COPY]](s32), [[COPY1]]
|
||||
%0:_(s32) = COPY $sgpr0
|
||||
%1:_(s32) = COPY $vgpr0
|
||||
%2:_(s1) = G_ICMP intpred(ne), %0, %1
|
||||
...
|
||||
|
||||
---
|
||||
name: icmp_vs
|
||||
legalized: true
|
||||
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $sgpr0, $vgpr0
|
||||
; CHECK-LABEL: name: icmp_vs
|
||||
; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0
|
||||
; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
|
||||
; CHECK: [[ICMP:%[0-9]+]]:sgpr(s1) = G_ICMP intpred(ne), [[COPY1]](s32), [[COPY]]
|
||||
%0:_(s32) = COPY $sgpr0
|
||||
%1:_(s32) = COPY $vgpr0
|
||||
%2:_(s1) = G_ICMP intpred(ne), %1, %0
|
||||
...
|
||||
|
||||
---
|
||||
name: icmp_vv
|
||||
legalized: true
|
||||
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $vgpr0, $vgpr1
|
||||
; CHECK-LABEL: name: icmp_vv
|
||||
; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
|
||||
; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1
|
||||
; CHECK: [[ICMP:%[0-9]+]]:sgpr(s1) = G_ICMP intpred(ne), [[COPY]](s32), [[COPY1]]
|
||||
%0:_(s32) = COPY $vgpr0
|
||||
%1:_(s32) = COPY $vgpr1
|
||||
%2:_(s1) = G_ICMP intpred(ne), %0, %1
|
||||
...
|
Loading…
Reference in New Issue