From 0f9eaaa8aa10bdb658e887782b86f03dbea79cb1 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 10 Oct 2013 17:11:24 +0000 Subject: [PATCH] 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 --- lib/Target/R600/AMDGPUInstrInfo.cpp | 9 +++++ lib/Target/R600/AMDGPUInstrInfo.h | 3 ++ lib/Target/R600/SIISelLowering.cpp | 2 + lib/Target/R600/SIInstrInfo.td | 61 ++++++++++++++++++++++++----- lib/Target/R600/SIInstructions.td | 50 +++++++++++------------ 5 files changed, 90 insertions(+), 35 deletions(-) diff --git a/lib/Target/R600/AMDGPUInstrInfo.cpp b/lib/Target/R600/AMDGPUInstrInfo.cpp index 8d3f740c3c5..bb7f97ff11d 100644 --- a/lib/Target/R600/AMDGPUInstrInfo.cpp +++ b/lib/Target/R600/AMDGPUInstrInfo.cpp @@ -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); + } +} diff --git a/lib/Target/R600/AMDGPUInstrInfo.h b/lib/Target/R600/AMDGPUInstrInfo.h index 306f467bc4b..4651859a178 100644 --- a/lib/Target/R600/AMDGPUInstrInfo.h +++ b/lib/Target/R600/AMDGPUInstrInfo.h @@ -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 { diff --git a/lib/Target/R600/SIISelLowering.cpp b/lib/Target/R600/SIISelLowering.cpp index 21747537b23..fb21f6e860c 100644 --- a/lib/Target/R600/SIISelLowering.cpp +++ b/lib/Target/R600/SIISelLowering.cpp @@ -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); } diff --git a/lib/Target/R600/SIInstrInfo.td b/lib/Target/R600/SIInstrInfo.td index e7d70f420cb..ed42a2ad954 100644 --- a/lib/Target/R600/SIInstrInfo.td +++ b/lib/Target/R600/SIInstrInfo.td @@ -472,10 +472,16 @@ class MTBUF_Load_Helper op, string asm, RegisterClass regClass> : MTBUF let mayStore = 0; } +class MIMG_Mask { + string Op = op; + int Channels = channels; +} + class MIMG_NoSampler_Helper 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 op, string asm, let hasPostISelHook = 1; } +multiclass MIMG_NoSampler_Src_Helper op, string asm, + RegisterClass dst_rc, + int channels> { + def _V1 : MIMG_NoSampler_Helper , + MIMG_Mask; + def _V2 : MIMG_NoSampler_Helper , + MIMG_Mask; + def _V4 : MIMG_NoSampler_Helper , + MIMG_Mask; +} + multiclass MIMG_NoSampler op, string asm> { - def _V1 : MIMG_NoSampler_Helper ; - def _V2 : MIMG_NoSampler_Helper ; - def _V4 : MIMG_NoSampler_Helper ; + defm _V1 : MIMG_NoSampler_Src_Helper ; + defm _V2 : MIMG_NoSampler_Src_Helper ; + defm _V3 : MIMG_NoSampler_Src_Helper ; + defm _V4 : MIMG_NoSampler_Src_Helper ; } class MIMG_Sampler_Helper 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 op, string asm, let hasPostISelHook = 1; } +multiclass MIMG_Sampler_Src_Helper op, string asm, + RegisterClass dst_rc, + int channels> { + def _V1 : MIMG_Sampler_Helper , + MIMG_Mask; + def _V2 : MIMG_Sampler_Helper , + MIMG_Mask; + def _V4 : MIMG_Sampler_Helper , + MIMG_Mask; + def _V8 : MIMG_Sampler_Helper , + MIMG_Mask; + def _V16 : MIMG_Sampler_Helper , + MIMG_Mask; +} + multiclass MIMG_Sampler op, string asm> { - def _V1 : MIMG_Sampler_Helper ; - def _V2 : MIMG_Sampler_Helper ; - def _V4 : MIMG_Sampler_Helper ; - def _V8 : MIMG_Sampler_Helper ; - def _V16 : MIMG_Sampler_Helper ; + defm _V1 : MIMG_Sampler_Src_Helper; + defm _V2 : MIMG_Sampler_Src_Helper; + defm _V3 : MIMG_Sampler_Src_Helper; + defm _V4 : MIMG_Sampler_Src_Helper; } //===----------------------------------------------------------------------===// @@ -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"; diff --git a/lib/Target/R600/SIInstructions.td b/lib/Target/R600/SIInstructions.td index 99fedcb95a4..d9cf1e5c571 100644 --- a/lib/Target/R600/SIInstructions.td +++ b/lib/Target/R600/SIInstructions.td @@ -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 : Pat < @@ -1399,25 +1399,25 @@ MIMG sample_d, MIMG sample_c_d, ValueType addr_type> { def : SampleShadowArrayPattern ; } -defm : SamplePatterns; -defm : SamplePatterns; -defm : SamplePatterns; -defm : SamplePatterns; /* int_SI_imageload for texture fetches consuming varying address parameters */ @@ -1451,26 +1451,26 @@ multiclass ImageLoadMSAAPatterns { def : ImageLoadArrayMSAAPattern ; } -defm : ImageLoadPatterns; -defm : ImageLoadPatterns; +defm : ImageLoadPatterns; +defm : ImageLoadPatterns; -defm : ImageLoadMSAAPatterns; -defm : ImageLoadMSAAPatterns; +defm : ImageLoadMSAAPatterns; +defm : ImageLoadMSAAPatterns; /* 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) >; /********** ============================================ **********/