R600/SI: Define a separate MIMG instruction for each possible output value type

During instruction selection, we rewrite the destination register
class for MIMG instructions based on their writemasks.  This creates
machine verifier errors since the new register class does not match
the register class in the MIMG instruction definition.

We can avoid this by defining different MIMG instructions for each
possible destination type and then switching to the correct instruction
when we change the register class.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192365 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tom Stellard 2013-10-10 17:11:24 +00:00
parent 219e788dc6
commit 0f9eaaa8aa
5 changed files with 90 additions and 35 deletions

View File

@ -244,3 +244,12 @@ void AMDGPUInstrInfo::convertToISA(MachineInstr & MI, MachineFunction &MF,
}
}
}
int AMDGPUInstrInfo::getMaskedMIMGOp(uint16_t Opcode, unsigned Channels) const {
switch (Channels) {
default: return Opcode;
case 1: return AMDGPU::getMaskedMIMGOp(Opcode, AMDGPU::Channels_1);
case 2: return AMDGPU::getMaskedMIMGOp(Opcode, AMDGPU::Channels_2);
case 3: return AMDGPU::getMaskedMIMGOp(Opcode, AMDGPU::Channels_3);
}
}

View File

@ -197,6 +197,9 @@ public:
virtual void convertToISA(MachineInstr & MI, MachineFunction &MF,
DebugLoc DL) const;
/// \brief Given a MIMG \p Opcode that writes all 4 channels, return the
/// equivalent opcode that writes \p Channels Channels.
int getMaskedMIMGOp(uint16_t Opcode, unsigned Channels) const;
};
namespace AMDGPU {

View File

@ -1162,6 +1162,8 @@ void SITargetLowering::AdjustInstrPostInstrSelection(MachineInstr *MI,
case 3: RC = &AMDGPU::VReg_96RegClass; break;
}
unsigned NewOpcode = TII->getMaskedMIMGOp(MI->getOpcode(), BitsSet);
MI->setDesc(TII->get(NewOpcode));
MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
MRI.setRegClass(VReg, RC);
}

View File

@ -472,10 +472,16 @@ class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF
let mayStore = 0;
}
class MIMG_Mask <string op, int channels> {
string Op = op;
int Channels = channels;
}
class MIMG_NoSampler_Helper <bits<7> op, string asm,
RegisterClass dst_rc,
RegisterClass src_rc> : MIMG <
op,
(outs VReg_128:$vdata),
(outs dst_rc:$vdata),
(ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
SReg_256:$srsrc),
@ -488,16 +494,29 @@ class MIMG_NoSampler_Helper <bits<7> op, string asm,
let hasPostISelHook = 1;
}
multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
RegisterClass dst_rc,
int channels> {
def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
MIMG_Mask<asm#"_V1", channels>;
def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
MIMG_Mask<asm#"_V2", channels>;
def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
MIMG_Mask<asm#"_V4", channels>;
}
multiclass MIMG_NoSampler <bits<7> op, string asm> {
def _V1 : MIMG_NoSampler_Helper <op, asm, VReg_32>;
def _V2 : MIMG_NoSampler_Helper <op, asm, VReg_64>;
def _V4 : MIMG_NoSampler_Helper <op, asm, VReg_128>;
defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
}
class MIMG_Sampler_Helper <bits<7> op, string asm,
RegisterClass dst_rc,
RegisterClass src_rc> : MIMG <
op,
(outs VReg_128:$vdata),
(outs dst_rc:$vdata),
(ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
SReg_256:$srsrc, SReg_128:$ssamp),
@ -509,12 +528,26 @@ class MIMG_Sampler_Helper <bits<7> op, string asm,
let hasPostISelHook = 1;
}
multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
RegisterClass dst_rc,
int channels> {
def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
MIMG_Mask<asm#"_V1", channels>;
def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
MIMG_Mask<asm#"_V2", channels>;
def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
MIMG_Mask<asm#"_V4", channels>;
def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
MIMG_Mask<asm#"_V8", channels>;
def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
MIMG_Mask<asm#"_V16", channels>;
}
multiclass MIMG_Sampler <bits<7> op, string asm> {
def _V1 : MIMG_Sampler_Helper <op, asm, VReg_32>;
def _V2 : MIMG_Sampler_Helper <op, asm, VReg_64>;
def _V4 : MIMG_Sampler_Helper <op, asm, VReg_128>;
def _V8 : MIMG_Sampler_Helper <op, asm, VReg_256>;
def _V16 : MIMG_Sampler_Helper <op, asm, VReg_512>;
defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
}
//===----------------------------------------------------------------------===//
@ -539,6 +572,14 @@ def getCommuteRev : InstrMapping {
let ValueCols = [["0"]];
}
def getMaskedMIMGOp : InstrMapping {
let FilterClass = "MIMG_Mask";
let RowFields = ["Op"];
let ColFields = ["Channels"];
let KeyCol = ["4"];
let ValueCols = [["1"], ["2"], ["3"] ];
}
// Maps an commuted opcode to its original version
def getCommuteOrig : InstrMapping {
let FilterClass = "VOP2_REV";

View File

@ -524,7 +524,7 @@ defm IMAGE_LOAD_MIP : MIMG_NoSampler <0x00000001, "IMAGE_LOAD_MIP">;
//def IMAGE_STORE_MIP : MIMG_NoPattern_ <"IMAGE_STORE_MIP", 0x00000009>;
//def IMAGE_STORE_PCK : MIMG_NoPattern_ <"IMAGE_STORE_PCK", 0x0000000a>;
//def IMAGE_STORE_MIP_PCK : MIMG_NoPattern_ <"IMAGE_STORE_MIP_PCK", 0x0000000b>;
def IMAGE_GET_RESINFO : MIMG_NoSampler_Helper <0x0000000e, "IMAGE_GET_RESINFO", VReg_32>;
defm IMAGE_GET_RESINFO : MIMG_NoSampler <0x0000000e, "IMAGE_GET_RESINFO">;
//def IMAGE_ATOMIC_SWAP : MIMG_NoPattern_ <"IMAGE_ATOMIC_SWAP", 0x0000000f>;
//def IMAGE_ATOMIC_CMPSWAP : MIMG_NoPattern_ <"IMAGE_ATOMIC_CMPSWAP", 0x00000010>;
//def IMAGE_ATOMIC_ADD : MIMG_NoPattern_ <"IMAGE_ATOMIC_ADD", 0x00000011>;
@ -1343,7 +1343,7 @@ def : Pat <
/* SIsample for simple 1D texture lookup */
def : Pat <
(SIsample i32:$addr, v32i8:$rsrc, i128:$sampler, imm),
(IMAGE_SAMPLE_V1 0xf, 0, 0, 0, 0, 0, 0, 0, $addr, $rsrc, $sampler)
(IMAGE_SAMPLE_V4_V1 0xf, 0, 0, 0, 0, 0, 0, 0, $addr, $rsrc, $sampler)
>;
class SamplePattern<SDNode name, MIMG opcode, ValueType vt> : Pat <
@ -1399,25 +1399,25 @@ MIMG sample_d, MIMG sample_c_d, ValueType addr_type> {
def : SampleShadowArrayPattern <SIsampled, sample_c_d, addr_type>;
}
defm : SamplePatterns<IMAGE_SAMPLE_V2, IMAGE_SAMPLE_C_V2,
IMAGE_SAMPLE_L_V2, IMAGE_SAMPLE_C_L_V2,
IMAGE_SAMPLE_B_V2, IMAGE_SAMPLE_C_B_V2,
IMAGE_SAMPLE_D_V2, IMAGE_SAMPLE_C_D_V2,
defm : SamplePatterns<IMAGE_SAMPLE_V4_V2, IMAGE_SAMPLE_C_V4_V2,
IMAGE_SAMPLE_L_V4_V2, IMAGE_SAMPLE_C_L_V4_V2,
IMAGE_SAMPLE_B_V4_V2, IMAGE_SAMPLE_C_B_V4_V2,
IMAGE_SAMPLE_D_V4_V2, IMAGE_SAMPLE_C_D_V4_V2,
v2i32>;
defm : SamplePatterns<IMAGE_SAMPLE_V4, IMAGE_SAMPLE_C_V4,
IMAGE_SAMPLE_L_V4, IMAGE_SAMPLE_C_L_V4,
IMAGE_SAMPLE_B_V4, IMAGE_SAMPLE_C_B_V4,
IMAGE_SAMPLE_D_V4, IMAGE_SAMPLE_C_D_V4,
defm : SamplePatterns<IMAGE_SAMPLE_V4_V4, IMAGE_SAMPLE_C_V4_V4,
IMAGE_SAMPLE_L_V4_V4, IMAGE_SAMPLE_C_L_V4_V4,
IMAGE_SAMPLE_B_V4_V4, IMAGE_SAMPLE_C_B_V4_V4,
IMAGE_SAMPLE_D_V4_V4, IMAGE_SAMPLE_C_D_V4_V4,
v4i32>;
defm : SamplePatterns<IMAGE_SAMPLE_V8, IMAGE_SAMPLE_C_V8,
IMAGE_SAMPLE_L_V8, IMAGE_SAMPLE_C_L_V8,
IMAGE_SAMPLE_B_V8, IMAGE_SAMPLE_C_B_V8,
IMAGE_SAMPLE_D_V8, IMAGE_SAMPLE_C_D_V8,
defm : SamplePatterns<IMAGE_SAMPLE_V4_V8, IMAGE_SAMPLE_C_V4_V8,
IMAGE_SAMPLE_L_V4_V8, IMAGE_SAMPLE_C_L_V4_V8,
IMAGE_SAMPLE_B_V4_V8, IMAGE_SAMPLE_C_B_V4_V8,
IMAGE_SAMPLE_D_V4_V8, IMAGE_SAMPLE_C_D_V4_V8,
v8i32>;
defm : SamplePatterns<IMAGE_SAMPLE_V16, IMAGE_SAMPLE_C_V16,
IMAGE_SAMPLE_L_V16, IMAGE_SAMPLE_C_L_V16,
IMAGE_SAMPLE_B_V16, IMAGE_SAMPLE_C_B_V16,
IMAGE_SAMPLE_D_V16, IMAGE_SAMPLE_C_D_V16,
defm : SamplePatterns<IMAGE_SAMPLE_V4_V16, IMAGE_SAMPLE_C_V4_V16,
IMAGE_SAMPLE_L_V4_V16, IMAGE_SAMPLE_C_L_V4_V16,
IMAGE_SAMPLE_B_V4_V16, IMAGE_SAMPLE_C_B_V4_V16,
IMAGE_SAMPLE_D_V4_V16, IMAGE_SAMPLE_C_D_V4_V16,
v16i32>;
/* int_SI_imageload for texture fetches consuming varying address parameters */
@ -1451,26 +1451,26 @@ multiclass ImageLoadMSAAPatterns<MIMG opcode, ValueType addr_type> {
def : ImageLoadArrayMSAAPattern <int_SI_imageload, opcode, addr_type>;
}
defm : ImageLoadPatterns<IMAGE_LOAD_MIP_V2, v2i32>;
defm : ImageLoadPatterns<IMAGE_LOAD_MIP_V4, v4i32>;
defm : ImageLoadPatterns<IMAGE_LOAD_MIP_V4_V2, v2i32>;
defm : ImageLoadPatterns<IMAGE_LOAD_MIP_V4_V4, v4i32>;
defm : ImageLoadMSAAPatterns<IMAGE_LOAD_V2, v2i32>;
defm : ImageLoadMSAAPatterns<IMAGE_LOAD_V4, v4i32>;
defm : ImageLoadMSAAPatterns<IMAGE_LOAD_V4_V2, v2i32>;
defm : ImageLoadMSAAPatterns<IMAGE_LOAD_V4_V4, v4i32>;
/* Image resource information */
def : Pat <
(int_SI_resinfo i32:$mipid, v32i8:$rsrc, imm),
(IMAGE_GET_RESINFO 0xf, 0, 0, 0, 0, 0, 0, 0, (V_MOV_B32_e32 $mipid), $rsrc)
(IMAGE_GET_RESINFO_V4_V1 0xf, 0, 0, 0, 0, 0, 0, 0, (V_MOV_B32_e32 $mipid), $rsrc)
>;
def : Pat <
(int_SI_resinfo i32:$mipid, v32i8:$rsrc, TEX_ARRAY),
(IMAGE_GET_RESINFO 0xf, 0, 0, 1, 0, 0, 0, 0, (V_MOV_B32_e32 $mipid), $rsrc)
(IMAGE_GET_RESINFO_V4_V1 0xf, 0, 0, 1, 0, 0, 0, 0, (V_MOV_B32_e32 $mipid), $rsrc)
>;
def : Pat <
(int_SI_resinfo i32:$mipid, v32i8:$rsrc, TEX_ARRAY_MSAA),
(IMAGE_GET_RESINFO 0xf, 0, 0, 1, 0, 0, 0, 0, (V_MOV_B32_e32 $mipid), $rsrc)
(IMAGE_GET_RESINFO_V4_V1 0xf, 0, 0, 1, 0, 0, 0, 0, (V_MOV_B32_e32 $mipid), $rsrc)
>;
/********** ============================================ **********/