R600: Add a llvm.R600.store.swizzle intrinsics
authorTom Stellard <thomas.stellard@amd.com>
Wed, 23 Jan 2013 21:39:49 +0000 (21:39 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Wed, 23 Jan 2013 21:39:49 +0000 (21:39 +0000)
This intrinsic is translated to ALLOC_EXPORT_WORD1_SWIZ, hence its
name. It is used to store vs/fs outputs

Patch by: Vincent Lejeune

Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173297 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/R600/R600ISelLowering.cpp
lib/Target/R600/R600Instructions.td
lib/Target/R600/R600Intrinsics.td

index 3434d7ec7d4aeb6d772951990c3f5a6c179d9bdb..3dc5b0076e438094b4fd596c108e270cd66ad1bf 100644 (file)
@@ -269,8 +269,24 @@ MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
 
   case AMDGPU::EG_ExportSwz:
   case AMDGPU::R600_ExportSwz: {
+    // Instruction is left unmodified if its not the last one of its type
+    bool isLastInstructionOfItsType = true;
+    unsigned InstExportType = MI->getOperand(1).getImm();
+    for (MachineBasicBlock::iterator NextExportInst = llvm::next(I),
+         EndBlock = BB->end(); NextExportInst != EndBlock;
+         NextExportInst = llvm::next(NextExportInst)) {
+      if (NextExportInst->getOpcode() == AMDGPU::EG_ExportSwz ||
+          NextExportInst->getOpcode() == AMDGPU::R600_ExportSwz) {
+        unsigned CurrentInstExportType = NextExportInst->getOperand(1)
+            .getImm();
+        if (CurrentInstExportType == InstExportType) {
+          isLastInstructionOfItsType = false;
+          break;
+        }
+      }
+    }
     bool EOP = (llvm::next(I)->getOpcode() == AMDGPU::RETURN)? 1 : 0;
-    if (!EOP)
+    if (!EOP && !isLastInstructionOfItsType)
       return BB;
     unsigned CfInst = (MI->getOpcode() == AMDGPU::EG_ExportSwz)? 84 : 40;
     BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode()))
@@ -282,7 +298,7 @@ MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
             .addOperand(MI->getOperand(5))
             .addOperand(MI->getOperand(6))
             .addImm(CfInst)
-            .addImm(1);
+            .addImm(EOP);
     break;
   }
   }
index 3e069da780244ea3e39a9807be691d967f5654f6..04b83bc87bfc9d641fdc4eeeb2add19a20b16194 100644 (file)
@@ -599,6 +599,17 @@ multiclass ExportPattern<Instruction ExportInst, bits<8> cf_inst> {
         (ExportInst R600_Reg128:$src, imm:$type, imm:$arraybase,
         0, 1, 2, 3, cf_inst, 0)
   >;
+  def : Pat<(EXPORT (v4f32 R600_Reg128:$src), (i32 1),
+    (i32 imm:$type), (i32 imm:$arraybase), (i32 imm)),
+        (ExportInst R600_Reg128:$src, imm:$type, imm:$arraybase,
+        0, 1, 2, 3, cf_inst, 0)
+  >;
+
+  def : Pat<(int_R600_store_swizzle (v4f32 R600_Reg128:$src), imm:$arraybase,
+      imm:$type),
+    (ExportInst R600_Reg128:$src, imm:$type, imm:$arraybase,
+        0, 1, 2, 3, cf_inst, 0)
+  >;
 }
 
 multiclass SteamOutputExportPattern<Instruction ExportInst,
index 06a734123fbc4b39befa5cfab661190115392741..1394a85461914641677aa7988de73a0e84469438 100644 (file)
@@ -19,6 +19,8 @@ let TargetPrefix = "R600", isTarget = 1 in {
     Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrReadMem]>;
   def int_R600_load_input_linear :
     Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrReadMem]>;
+  def int_R600_store_swizzle :
+    Intrinsic<[], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty], []>;
   def int_R600_store_stream_output :
     Intrinsic<[], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
   def int_R600_store_pixel_color :