R600/SI: Define a separate MIMG instruction for each possible output value type
authorTom Stellard <thomas.stellard@amd.com>
Thu, 10 Oct 2013 17:11:24 +0000 (17:11 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Thu, 10 Oct 2013 17:11:24 +0000 (17:11 +0000)
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
lib/Target/R600/AMDGPUInstrInfo.h
lib/Target/R600/SIISelLowering.cpp
lib/Target/R600/SIInstrInfo.td
lib/Target/R600/SIInstructions.td

index 8d3f740c3c589594f8a5a9e261367c75485b5671..bb7f97ff11dac43ea3f7ee37f2af6c80af34ab4b 100644 (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);
+  }
+}
index 306f467bc4b2b9d219bbfd9c62f6870028819751..4651859a178d7eeba36f64f2ee26605df303be2e 100644 (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 {
index 21747537b23fbb6403cd39e432d8c3bf60ea1ec4..fb21f6e860cf42704590ed2d0cd25c9d9c53e41c 100644 (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);
 }
index e7d70f420cb6bacf474791b3b7ec03a5b1f426bc..ed42a2ad954161ea363e3cbf5fa4677b315d4178 100644 (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";
index 99fedcb95a43cffc90a29fc24cacb2f90f5688b9..d9cf1e5c5711b62d74f7eace9a750b2883442ed7 100644 (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)
 >;
 
 /********** ============================================ **********/