]> granicus.if.org Git - llvm/commitdiff
[AMDGPU] Add missing hazard for DPP-after-EXEC-write
authorConnor Abbott <cwabbott0@gmail.com>
Fri, 4 Aug 2017 01:09:43 +0000 (01:09 +0000)
committerConnor Abbott <cwabbott0@gmail.com>
Fri, 4 Aug 2017 01:09:43 +0000 (01:09 +0000)
Summary:
Following the docs, we need at least 5 wait states between an EXEC write
and an instruction that uses DPP.

Reviewers: tstellar, arsenm

Subscribers: kzhuravl, wdng, nhaehnle, yaxunl, dstuttard, tpr, t-tye, llvm-commits

Differential Revision: https://reviews.llvm.org/D34849

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310013 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AMDGPU/GCNHazardRecognizer.cpp
test/CodeGen/AMDGPU/inserted-wait-states.mir

index cd9e7fb04f16b0161c7b596dddf5a198dd8ea682..b601cfeded100f9af5c05a32c08eee96e7cda85f 100644 (file)
@@ -367,10 +367,13 @@ int GCNHazardRecognizer::checkVMEMHazards(MachineInstr* VMEM) {
 
 int GCNHazardRecognizer::checkDPPHazards(MachineInstr *DPP) {
   const SIRegisterInfo *TRI = ST.getRegisterInfo();
+  const SIInstrInfo *TII = ST.getInstrInfo();
 
-  // Check for DPP VGPR read after VALU VGPR write.
+  // Check for DPP VGPR read after VALU VGPR write and EXEC write.
   int DppVgprWaitStates = 2;
+  int DppExecWaitStates = 5;
   int WaitStatesNeeded = 0;
+  auto IsHazardDefFn = [TII] (MachineInstr *MI) { return TII->isVALU(*MI); };
 
   for (const MachineOperand &Use : DPP->uses()) {
     if (!Use.isReg() || !TRI->isVGPR(MF.getRegInfo(), Use.getReg()))
@@ -380,6 +383,10 @@ int GCNHazardRecognizer::checkDPPHazards(MachineInstr *DPP) {
     WaitStatesNeeded = std::max(WaitStatesNeeded, WaitStatesNeededForUse);
   }
 
+  WaitStatesNeeded = std::max(
+      WaitStatesNeeded,
+      DppExecWaitStates - getWaitStatesSinceDef(AMDGPU::EXEC, IsHazardDefFn));
+
   return WaitStatesNeeded;
 }
 
index c6fe6debd225a8cae3d9c0d015eb284e793394d8..bf4c7cbe6ee8dc0f81abe4e9147023d14eaf86fc 100644 (file)
@@ -13,6 +13,7 @@
   define amdgpu_kernel void @s_mov_fed_b32() { ret void }
   define amdgpu_kernel void @s_movrel() { ret void }
   define amdgpu_kernel void @v_interp() { ret void }
+  define amdgpu_kernel void @dpp() { ret void }
 
   define amdgpu_kernel void @mov_fed_hazard_crash_on_dbg_value(i32 addrspace(1)* %A) {
   entry:
@@ -477,6 +478,40 @@ body: |
     %vgpr0 = V_INTERP_MOV_F32 0, 0, 0, implicit %m0, implicit %exec
     S_ENDPGM
 ...
+
+...
+---
+
+# GCN-LABEL: name: dpp
+
+# VI-LABEL: bb.0:
+# VI: V_MOV_B32_e32
+# VI-NEXT: S_NOP 0
+# VI-NEXT: S_NOP 0
+# VI-NEXT: V_MOV_B32_dpp
+
+# VI-LABEL: bb.1:
+# VI: V_CMPX_EQ_I32_e32
+# VI-NEXT: S_NOP 0
+# VI-NEXT: S_NOP 0
+# VI-NEXT: S_NOP 0
+# VI-NEXT: S_NOP 0
+# VI-NEXT: S_NOP 0
+# VI-NEXT: V_MOV_B32_dpp
+
+name: dpp
+
+body: |
+  bb.0:
+    %vgpr0 = V_MOV_B32_e32 0, implicit %exec
+    %vgpr1 = V_MOV_B32_dpp %vgpr0, 0, 15, 15, 0, implicit %exec
+    S_BRANCH %bb.1
+
+  bb.1:
+    implicit %exec, implicit %vcc = V_CMPX_EQ_I32_e32 %vgpr0, %vgpr1, implicit %exec
+    %vgpr3 = V_MOV_B32_dpp %vgpr0, 0, 15, 15, 0, implicit %exec
+    S_ENDPGM
+...
 ---
 name:            mov_fed_hazard_crash_on_dbg_value
 alignment:       0