[llvm] 7f2a641 - [AMDGPU] Insert waterfall loops for divergent calls

Sebastian Neubauer via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 12 08:16:46 PDT 2020


Author: Sebastian Neubauer
Date: 2020-10-12T17:16:11+02:00
New Revision: 7f2a641aad28fd9b15fa1bcae1dd496150638d79

URL: https://github.com/llvm/llvm-project/commit/7f2a641aad28fd9b15fa1bcae1dd496150638d79
DIFF: https://github.com/llvm/llvm-project/commit/7f2a641aad28fd9b15fa1bcae1dd496150638d79.diff

LOG: [AMDGPU] Insert waterfall loops for divergent calls

Extend loadSRsrcFromVGPR to allow moving a range of instructions into
the loop. The call instruction is surrounded by copies into physical
registers which should be part of the waterfall loop.

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

Added: 
    

Modified: 
    llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
    llvm/test/CodeGen/AMDGPU/indirect-call.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index 86eb594489a9..a2cbe2735220 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -4700,9 +4700,13 @@ emitLoadSRsrcFromVGPRLoop(const SIInstrInfo &TII, MachineRegisterInfo &MRI,
             .addImm(AMDGPU::sub1);
 
     Register NewCondReg = MRI.createVirtualRegister(BoolXExecRC);
-    BuildMI(LoopBB, I, DL, TII.get(AMDGPU::V_CMP_EQ_U64_e64), NewCondReg)
-           .addReg(CurReg)
-           .addReg(VRsrc, VRsrcUndef, TRI->getSubRegFromChannel(Idx, 2));
+    auto Cmp =
+        BuildMI(LoopBB, I, DL, TII.get(AMDGPU::V_CMP_EQ_U64_e64), NewCondReg)
+            .addReg(CurReg);
+    if (NumSubRegs <= 2)
+      Cmp.addReg(VRsrc);
+    else
+      Cmp.addReg(VRsrc, VRsrcUndef, TRI->getSubRegFromChannel(Idx, 2));
 
     // Combine the comparision results with AND.
     if (CondReg == AMDGPU::NoRegister) // First.
@@ -4752,13 +4756,20 @@ emitLoadSRsrcFromVGPRLoop(const SIInstrInfo &TII, MachineRegisterInfo &MRI,
 // Build a waterfall loop around \p MI, replacing the VGPR \p Rsrc register
 // with SGPRs by iterating over all unique values across all lanes.
 static void loadSRsrcFromVGPR(const SIInstrInfo &TII, MachineInstr &MI,
-                              MachineOperand &Rsrc, MachineDominatorTree *MDT) {
+                              MachineOperand &Rsrc, MachineDominatorTree *MDT,
+                              MachineBasicBlock::iterator Begin = nullptr,
+                              MachineBasicBlock::iterator End = nullptr) {
   MachineBasicBlock &MBB = *MI.getParent();
   MachineFunction &MF = *MBB.getParent();
   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
   const SIRegisterInfo *TRI = ST.getRegisterInfo();
   MachineRegisterInfo &MRI = MF.getRegInfo();
-  MachineBasicBlock::iterator I(&MI);
+  if (!Begin.isValid())
+    Begin = &MI;
+  if (!End.isValid()) {
+    End = &MI;
+    ++End;
+  }
   const DebugLoc &DL = MI.getDebugLoc();
   unsigned Exec = ST.isWave32() ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
   unsigned MovExecOpc = ST.isWave32() ? AMDGPU::S_MOV_B32 : AMDGPU::S_MOV_B64;
@@ -4767,13 +4778,17 @@ static void loadSRsrcFromVGPR(const SIInstrInfo &TII, MachineInstr &MI,
   Register SaveExec = MRI.createVirtualRegister(BoolXExecRC);
 
   // Save the EXEC mask
-  BuildMI(MBB, I, DL, TII.get(MovExecOpc), SaveExec).addReg(Exec);
+  BuildMI(MBB, Begin, DL, TII.get(MovExecOpc), SaveExec).addReg(Exec);
 
   // Killed uses in the instruction we are waterfalling around will be
   // incorrect due to the added control-flow.
-  for (auto &MO : MI.uses()) {
-    if (MO.isReg() && MO.isUse()) {
-      MRI.clearKillFlags(MO.getReg());
+  MachineBasicBlock::iterator AfterMI = MI;
+  ++AfterMI;
+  for (auto I = Begin; I != AfterMI; I++) {
+    for (auto &MO : I->uses()) {
+      if (MO.isReg() && MO.isUse()) {
+        MRI.clearKillFlags(MO.getReg());
+      }
     }
   }
 
@@ -4790,11 +4805,11 @@ static void loadSRsrcFromVGPR(const SIInstrInfo &TII, MachineInstr &MI,
   LoopBB->addSuccessor(LoopBB);
   LoopBB->addSuccessor(RemainderBB);
 
-  // Move MI to the LoopBB, and the remainder of the block to RemainderBB.
-  MachineBasicBlock::iterator J = I++;
+  // Move Begin to MI to the LoopBB, and the remainder of the block to
+  // RemainderBB.
   RemainderBB->transferSuccessorsAndUpdatePHIs(&MBB);
-  RemainderBB->splice(RemainderBB->begin(), &MBB, I, MBB.end());
-  LoopBB->splice(LoopBB->begin(), &MBB, J);
+  RemainderBB->splice(RemainderBB->begin(), &MBB, End, MBB.end());
+  LoopBB->splice(LoopBB->begin(), &MBB, Begin, MBB.end());
 
   MBB.addSuccessor(LoopBB);
 
@@ -5016,6 +5031,34 @@ void SIInstrInfo::legalizeOperands(MachineInstr &MI,
     return;
   }
 
+  // Legalize SI_CALL
+  if (MI.getOpcode() == AMDGPU::SI_CALL_ISEL) {
+    MachineOperand *Dest = &MI.getOperand(0);
+    if (!RI.isSGPRClass(MRI.getRegClass(Dest->getReg()))) {
+      // Move everything between ADJCALLSTACKUP and ADJCALLSTACKDOWN and
+      // following copies, we also need to move copies from and to physical
+      // registers into the loop block.
+      const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
+      unsigned FrameSetupOpcode = TII.getCallFrameSetupOpcode();
+      unsigned FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
+
+      // Also move the copies to physical registers into the loop block
+      MachineBasicBlock &MBB = *MI.getParent();
+      MachineBasicBlock::iterator Start(&MI);
+      while (Start->getOpcode() != FrameSetupOpcode)
+        --Start;
+      MachineBasicBlock::iterator End(&MI);
+      while (End->getOpcode() != FrameDestroyOpcode)
+        ++End;
+      // Also include following copies of the return value
+      ++End;
+      while (End != MBB.end() && End->isCopy() && End->getOperand(1).isReg() &&
+             MI.definesRegister(End->getOperand(1).getReg()))
+        ++End;
+      loadSRsrcFromVGPR(*this, MI, *Dest, MDT, Start, End);
+    }
+  }
+
   // Legalize MUBUF* instructions.
   int RsrcIdx =
       AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::srsrc);

diff  --git a/llvm/test/CodeGen/AMDGPU/indirect-call.ll b/llvm/test/CodeGen/AMDGPU/indirect-call.ll
index 459d9ca8bfcd..d182ecfccf7e 100644
--- a/llvm/test/CodeGen/AMDGPU/indirect-call.ll
+++ b/llvm/test/CodeGen/AMDGPU/indirect-call.ll
@@ -197,13 +197,275 @@ define amdgpu_kernel void @test_indirect_call_sgpr_ptr_arg() {
   ret void
 }
 
-; FIXME
-; define void @test_indirect_call_vgpr_ptr(void()* %fptr) {
-;   call void %fptr()
-;   ret void
-; }
+define void @test_indirect_call_vgpr_ptr(void()* %fptr) {
+; GCN-LABEL: test_indirect_call_vgpr_ptr:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    s_or_saveexec_b64 s[16:17], -1
+; GCN-NEXT:    buffer_store_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Spill
+; GCN-NEXT:    s_mov_b64 exec, s[16:17]
+; GCN-NEXT:    v_writelane_b32 v43, s33, 17
+; GCN-NEXT:    s_mov_b32 s33, s32
+; GCN-NEXT:    s_add_u32 s32, s32, 0x800
+; GCN-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; GCN-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; GCN-NEXT:    buffer_store_dword v42, off, s[0:3], s33 ; 4-byte Folded Spill
+; GCN-NEXT:    v_writelane_b32 v43, s34, 0
+; GCN-NEXT:    v_writelane_b32 v43, s35, 1
+; GCN-NEXT:    v_writelane_b32 v43, s36, 2
+; GCN-NEXT:    v_writelane_b32 v43, s38, 3
+; GCN-NEXT:    v_writelane_b32 v43, s39, 4
+; GCN-NEXT:    v_writelane_b32 v43, s40, 5
+; GCN-NEXT:    v_writelane_b32 v43, s41, 6
+; GCN-NEXT:    v_writelane_b32 v43, s42, 7
+; GCN-NEXT:    v_writelane_b32 v43, s43, 8
+; GCN-NEXT:    v_writelane_b32 v43, s44, 9
+; GCN-NEXT:    v_writelane_b32 v43, s45, 10
+; GCN-NEXT:    v_writelane_b32 v43, s46, 11
+; GCN-NEXT:    v_writelane_b32 v43, s47, 12
+; GCN-NEXT:    v_writelane_b32 v43, s48, 13
+; GCN-NEXT:    v_writelane_b32 v43, s49, 14
+; GCN-NEXT:    v_writelane_b32 v43, s30, 15
+; GCN-NEXT:    v_writelane_b32 v43, s31, 16
+; GCN-NEXT:    v_mov_b32_e32 v40, v31
+; GCN-NEXT:    s_mov_b32 s34, s14
+; GCN-NEXT:    s_mov_b32 s35, s13
+; GCN-NEXT:    s_mov_b32 s36, s12
+; GCN-NEXT:    s_mov_b64 s[38:39], s[10:11]
+; GCN-NEXT:    s_mov_b64 s[40:41], s[8:9]
+; GCN-NEXT:    s_mov_b64 s[42:43], s[6:7]
+; GCN-NEXT:    s_mov_b64 s[44:45], s[4:5]
+; GCN-NEXT:    v_mov_b32_e32 v42, v1
+; GCN-NEXT:    v_mov_b32_e32 v41, v0
+; GCN-NEXT:    s_mov_b64 s[46:47], exec
+; GCN-NEXT:  BB2_1: ; =>This Inner Loop Header: Depth=1
+; GCN-NEXT:    v_readfirstlane_b32 s16, v41
+; GCN-NEXT:    v_readfirstlane_b32 s17, v42
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, s[16:17], v[41:42]
+; GCN-NEXT:    s_and_saveexec_b64 s[48:49], vcc
+; GCN-NEXT:    s_mov_b64 s[4:5], s[44:45]
+; GCN-NEXT:    s_mov_b64 s[6:7], s[42:43]
+; GCN-NEXT:    s_mov_b64 s[8:9], s[40:41]
+; GCN-NEXT:    s_mov_b64 s[10:11], s[38:39]
+; GCN-NEXT:    s_mov_b32 s12, s36
+; GCN-NEXT:    s_mov_b32 s13, s35
+; GCN-NEXT:    s_mov_b32 s14, s34
+; GCN-NEXT:    v_mov_b32_e32 v31, v40
+; GCN-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; GCN-NEXT:    s_xor_b64 exec, exec, s[48:49]
+; GCN-NEXT:    s_cbranch_execnz BB2_1
+; GCN-NEXT:  ; %bb.2:
+; GCN-NEXT:    s_mov_b64 exec, s[46:47]
+; GCN-NEXT:    v_readlane_b32 s4, v43, 15
+; GCN-NEXT:    v_readlane_b32 s5, v43, 16
+; GCN-NEXT:    v_readlane_b32 s49, v43, 14
+; GCN-NEXT:    v_readlane_b32 s48, v43, 13
+; GCN-NEXT:    v_readlane_b32 s47, v43, 12
+; GCN-NEXT:    v_readlane_b32 s46, v43, 11
+; GCN-NEXT:    v_readlane_b32 s45, v43, 10
+; GCN-NEXT:    v_readlane_b32 s44, v43, 9
+; GCN-NEXT:    v_readlane_b32 s43, v43, 8
+; GCN-NEXT:    v_readlane_b32 s42, v43, 7
+; GCN-NEXT:    v_readlane_b32 s41, v43, 6
+; GCN-NEXT:    v_readlane_b32 s40, v43, 5
+; GCN-NEXT:    v_readlane_b32 s39, v43, 4
+; GCN-NEXT:    v_readlane_b32 s38, v43, 3
+; GCN-NEXT:    v_readlane_b32 s36, v43, 2
+; GCN-NEXT:    v_readlane_b32 s35, v43, 1
+; GCN-NEXT:    v_readlane_b32 s34, v43, 0
+; GCN-NEXT:    buffer_load_dword v42, off, s[0:3], s33 ; 4-byte Folded Reload
+; GCN-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; GCN-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; GCN-NEXT:    s_sub_u32 s32, s32, 0x800
+; GCN-NEXT:    v_readlane_b32 s33, v43, 17
+; GCN-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; GCN-NEXT:    buffer_load_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Reload
+; GCN-NEXT:    s_mov_b64 exec, s[6:7]
+; GCN-NEXT:    s_waitcnt vmcnt(0)
+; GCN-NEXT:    s_setpc_b64 s[4:5]
+  call void %fptr()
+  ret void
+}
 
-; define void @test_indirect_call_vgpr_ptr_arg(void(i32)* %fptr) {
-;   call void %fptr(i32 123)
-;   ret void
-; }
+define void @test_indirect_call_vgpr_ptr_arg(void(i32)* %fptr) {
+; GCN-LABEL: test_indirect_call_vgpr_ptr_arg:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    s_or_saveexec_b64 s[16:17], -1
+; GCN-NEXT:    buffer_store_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Spill
+; GCN-NEXT:    s_mov_b64 exec, s[16:17]
+; GCN-NEXT:    v_writelane_b32 v43, s33, 17
+; GCN-NEXT:    s_mov_b32 s33, s32
+; GCN-NEXT:    s_add_u32 s32, s32, 0x800
+; GCN-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; GCN-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; GCN-NEXT:    buffer_store_dword v42, off, s[0:3], s33 ; 4-byte Folded Spill
+; GCN-NEXT:    v_writelane_b32 v43, s34, 0
+; GCN-NEXT:    v_writelane_b32 v43, s35, 1
+; GCN-NEXT:    v_writelane_b32 v43, s36, 2
+; GCN-NEXT:    v_writelane_b32 v43, s38, 3
+; GCN-NEXT:    v_writelane_b32 v43, s39, 4
+; GCN-NEXT:    v_writelane_b32 v43, s40, 5
+; GCN-NEXT:    v_writelane_b32 v43, s41, 6
+; GCN-NEXT:    v_writelane_b32 v43, s42, 7
+; GCN-NEXT:    v_writelane_b32 v43, s43, 8
+; GCN-NEXT:    v_writelane_b32 v43, s44, 9
+; GCN-NEXT:    v_writelane_b32 v43, s45, 10
+; GCN-NEXT:    v_writelane_b32 v43, s46, 11
+; GCN-NEXT:    v_writelane_b32 v43, s47, 12
+; GCN-NEXT:    v_writelane_b32 v43, s48, 13
+; GCN-NEXT:    v_writelane_b32 v43, s49, 14
+; GCN-NEXT:    v_writelane_b32 v43, s30, 15
+; GCN-NEXT:    v_writelane_b32 v43, s31, 16
+; GCN-NEXT:    v_mov_b32_e32 v40, v31
+; GCN-NEXT:    s_mov_b32 s34, s14
+; GCN-NEXT:    s_mov_b32 s35, s13
+; GCN-NEXT:    s_mov_b32 s36, s12
+; GCN-NEXT:    s_mov_b64 s[38:39], s[10:11]
+; GCN-NEXT:    s_mov_b64 s[40:41], s[8:9]
+; GCN-NEXT:    s_mov_b64 s[42:43], s[6:7]
+; GCN-NEXT:    s_mov_b64 s[44:45], s[4:5]
+; GCN-NEXT:    v_mov_b32_e32 v42, v1
+; GCN-NEXT:    v_mov_b32_e32 v41, v0
+; GCN-NEXT:    s_mov_b64 s[46:47], exec
+; GCN-NEXT:  BB3_1: ; =>This Inner Loop Header: Depth=1
+; GCN-NEXT:    v_readfirstlane_b32 s16, v41
+; GCN-NEXT:    v_readfirstlane_b32 s17, v42
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, s[16:17], v[41:42]
+; GCN-NEXT:    s_and_saveexec_b64 s[48:49], vcc
+; GCN-NEXT:    v_mov_b32_e32 v0, 0x7b
+; GCN-NEXT:    s_mov_b64 s[4:5], s[44:45]
+; GCN-NEXT:    s_mov_b64 s[6:7], s[42:43]
+; GCN-NEXT:    s_mov_b64 s[8:9], s[40:41]
+; GCN-NEXT:    s_mov_b64 s[10:11], s[38:39]
+; GCN-NEXT:    s_mov_b32 s12, s36
+; GCN-NEXT:    s_mov_b32 s13, s35
+; GCN-NEXT:    s_mov_b32 s14, s34
+; GCN-NEXT:    v_mov_b32_e32 v31, v40
+; GCN-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; GCN-NEXT:    s_xor_b64 exec, exec, s[48:49]
+; GCN-NEXT:    s_cbranch_execnz BB3_1
+; GCN-NEXT:  ; %bb.2:
+; GCN-NEXT:    s_mov_b64 exec, s[46:47]
+; GCN-NEXT:    v_readlane_b32 s4, v43, 15
+; GCN-NEXT:    v_readlane_b32 s5, v43, 16
+; GCN-NEXT:    v_readlane_b32 s49, v43, 14
+; GCN-NEXT:    v_readlane_b32 s48, v43, 13
+; GCN-NEXT:    v_readlane_b32 s47, v43, 12
+; GCN-NEXT:    v_readlane_b32 s46, v43, 11
+; GCN-NEXT:    v_readlane_b32 s45, v43, 10
+; GCN-NEXT:    v_readlane_b32 s44, v43, 9
+; GCN-NEXT:    v_readlane_b32 s43, v43, 8
+; GCN-NEXT:    v_readlane_b32 s42, v43, 7
+; GCN-NEXT:    v_readlane_b32 s41, v43, 6
+; GCN-NEXT:    v_readlane_b32 s40, v43, 5
+; GCN-NEXT:    v_readlane_b32 s39, v43, 4
+; GCN-NEXT:    v_readlane_b32 s38, v43, 3
+; GCN-NEXT:    v_readlane_b32 s36, v43, 2
+; GCN-NEXT:    v_readlane_b32 s35, v43, 1
+; GCN-NEXT:    v_readlane_b32 s34, v43, 0
+; GCN-NEXT:    buffer_load_dword v42, off, s[0:3], s33 ; 4-byte Folded Reload
+; GCN-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; GCN-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; GCN-NEXT:    s_sub_u32 s32, s32, 0x800
+; GCN-NEXT:    v_readlane_b32 s33, v43, 17
+; GCN-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; GCN-NEXT:    buffer_load_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Reload
+; GCN-NEXT:    s_mov_b64 exec, s[6:7]
+; GCN-NEXT:    s_waitcnt vmcnt(0)
+; GCN-NEXT:    s_setpc_b64 s[4:5]
+  call void %fptr(i32 123)
+  ret void
+}
+
+define i32 @test_indirect_call_vgpr_ptr_ret(i32()* %fptr) {
+; GCN-LABEL: test_indirect_call_vgpr_ptr_ret:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    s_or_saveexec_b64 s[16:17], -1
+; GCN-NEXT:    buffer_store_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Spill
+; GCN-NEXT:    s_mov_b64 exec, s[16:17]
+; GCN-NEXT:    v_writelane_b32 v43, s33, 17
+; GCN-NEXT:    s_mov_b32 s33, s32
+; GCN-NEXT:    s_add_u32 s32, s32, 0x800
+; GCN-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
+; GCN-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
+; GCN-NEXT:    buffer_store_dword v42, off, s[0:3], s33 ; 4-byte Folded Spill
+; GCN-NEXT:    v_writelane_b32 v43, s34, 0
+; GCN-NEXT:    v_writelane_b32 v43, s35, 1
+; GCN-NEXT:    v_writelane_b32 v43, s36, 2
+; GCN-NEXT:    v_writelane_b32 v43, s38, 3
+; GCN-NEXT:    v_writelane_b32 v43, s39, 4
+; GCN-NEXT:    v_writelane_b32 v43, s40, 5
+; GCN-NEXT:    v_writelane_b32 v43, s41, 6
+; GCN-NEXT:    v_writelane_b32 v43, s42, 7
+; GCN-NEXT:    v_writelane_b32 v43, s43, 8
+; GCN-NEXT:    v_writelane_b32 v43, s44, 9
+; GCN-NEXT:    v_writelane_b32 v43, s45, 10
+; GCN-NEXT:    v_writelane_b32 v43, s46, 11
+; GCN-NEXT:    v_writelane_b32 v43, s47, 12
+; GCN-NEXT:    v_writelane_b32 v43, s48, 13
+; GCN-NEXT:    v_writelane_b32 v43, s49, 14
+; GCN-NEXT:    v_writelane_b32 v43, s30, 15
+; GCN-NEXT:    v_writelane_b32 v43, s31, 16
+; GCN-NEXT:    v_mov_b32_e32 v40, v31
+; GCN-NEXT:    s_mov_b32 s34, s14
+; GCN-NEXT:    s_mov_b32 s35, s13
+; GCN-NEXT:    s_mov_b32 s36, s12
+; GCN-NEXT:    s_mov_b64 s[38:39], s[10:11]
+; GCN-NEXT:    s_mov_b64 s[40:41], s[8:9]
+; GCN-NEXT:    s_mov_b64 s[42:43], s[6:7]
+; GCN-NEXT:    s_mov_b64 s[44:45], s[4:5]
+; GCN-NEXT:    v_mov_b32_e32 v42, v1
+; GCN-NEXT:    v_mov_b32_e32 v41, v0
+; GCN-NEXT:    s_mov_b64 s[46:47], exec
+; GCN-NEXT:  BB4_1: ; =>This Inner Loop Header: Depth=1
+; GCN-NEXT:    v_readfirstlane_b32 s16, v41
+; GCN-NEXT:    v_readfirstlane_b32 s17, v42
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, s[16:17], v[41:42]
+; GCN-NEXT:    s_and_saveexec_b64 s[48:49], vcc
+; GCN-NEXT:    s_mov_b64 s[4:5], s[44:45]
+; GCN-NEXT:    s_mov_b64 s[6:7], s[42:43]
+; GCN-NEXT:    s_mov_b64 s[8:9], s[40:41]
+; GCN-NEXT:    s_mov_b64 s[10:11], s[38:39]
+; GCN-NEXT:    s_mov_b32 s12, s36
+; GCN-NEXT:    s_mov_b32 s13, s35
+; GCN-NEXT:    s_mov_b32 s14, s34
+; GCN-NEXT:    v_mov_b32_e32 v31, v40
+; GCN-NEXT:    s_swappc_b64 s[30:31], s[16:17]
+; GCN-NEXT:    s_xor_b64 exec, exec, s[48:49]
+; GCN-NEXT:    s_cbranch_execnz BB4_1
+; GCN-NEXT:  ; %bb.2:
+; GCN-NEXT:    s_mov_b64 exec, s[46:47]
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, 1, v0
+; GCN-NEXT:    v_readlane_b32 s4, v43, 15
+; GCN-NEXT:    v_readlane_b32 s5, v43, 16
+; GCN-NEXT:    v_readlane_b32 s49, v43, 14
+; GCN-NEXT:    v_readlane_b32 s48, v43, 13
+; GCN-NEXT:    v_readlane_b32 s47, v43, 12
+; GCN-NEXT:    v_readlane_b32 s46, v43, 11
+; GCN-NEXT:    v_readlane_b32 s45, v43, 10
+; GCN-NEXT:    v_readlane_b32 s44, v43, 9
+; GCN-NEXT:    v_readlane_b32 s43, v43, 8
+; GCN-NEXT:    v_readlane_b32 s42, v43, 7
+; GCN-NEXT:    v_readlane_b32 s41, v43, 6
+; GCN-NEXT:    v_readlane_b32 s40, v43, 5
+; GCN-NEXT:    v_readlane_b32 s39, v43, 4
+; GCN-NEXT:    v_readlane_b32 s38, v43, 3
+; GCN-NEXT:    v_readlane_b32 s36, v43, 2
+; GCN-NEXT:    v_readlane_b32 s35, v43, 1
+; GCN-NEXT:    v_readlane_b32 s34, v43, 0
+; GCN-NEXT:    buffer_load_dword v42, off, s[0:3], s33 ; 4-byte Folded Reload
+; GCN-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
+; GCN-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
+; GCN-NEXT:    s_sub_u32 s32, s32, 0x800
+; GCN-NEXT:    v_readlane_b32 s33, v43, 17
+; GCN-NEXT:    s_or_saveexec_b64 s[6:7], -1
+; GCN-NEXT:    buffer_load_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Reload
+; GCN-NEXT:    s_mov_b64 exec, s[6:7]
+; GCN-NEXT:    s_waitcnt vmcnt(0)
+; GCN-NEXT:    s_setpc_b64 s[4:5]
+  %a = call i32 %fptr()
+  %b = add i32 %a, 1
+  ret i32 %b
+}


        


More information about the llvm-commits mailing list