[llvm] r204475 - R600/SI: Handle S_MOV_B64 in SIInstrInfo::moveToVALU()

Tom Stellard thomas.stellard at amd.com
Fri Mar 21 08:51:55 PDT 2014


Author: tstellar
Date: Fri Mar 21 10:51:54 2014
New Revision: 204475

URL: http://llvm.org/viewvc/llvm-project?rev=204475&view=rev
Log:
R600/SI: Handle S_MOV_B64 in SIInstrInfo::moveToVALU()

Added:
    llvm/trunk/test/CodeGen/R600/salu-to-valu.ll
Modified:
    llvm/trunk/lib/Target/R600/SIInstrInfo.cpp

Modified: llvm/trunk/lib/Target/R600/SIInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/SIInstrInfo.cpp?rev=204475&r1=204474&r2=204475&view=diff
==============================================================================
--- llvm/trunk/lib/Target/R600/SIInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/R600/SIInstrInfo.cpp Fri Mar 21 10:51:54 2014
@@ -496,6 +496,9 @@ unsigned SIInstrInfo::getVALUOp(const Ma
   case AMDGPU::REG_SEQUENCE: return AMDGPU::REG_SEQUENCE;
   case AMDGPU::COPY: return AMDGPU::COPY;
   case AMDGPU::PHI: return AMDGPU::PHI;
+  case AMDGPU::S_MOV_B32:
+    return MI.getOperand(1).isReg() ?
+           TargetOpcode::COPY : AMDGPU::V_MOV_B32_e32;
   case AMDGPU::S_ADD_I32: return AMDGPU::V_ADD_I32_e32;
   case AMDGPU::S_ADDC_U32: return AMDGPU::V_ADDC_U32_e32;
   case AMDGPU::S_SUB_I32: return AMDGPU::V_SUB_I32_e32;
@@ -680,12 +683,57 @@ void SIInstrInfo::moveToVALU(MachineInst
 
   while (!Worklist.empty()) {
     MachineInstr *Inst = Worklist.pop_back_val();
+    MachineBasicBlock *MBB = Inst->getParent();
+    MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
+
+    // Handle some special cases
+    switch(Inst->getOpcode()) {
+      case AMDGPU::S_MOV_B64: {
+        DebugLoc DL = Inst->getDebugLoc();
+
+        // If the source operand is a register we can replace this with a
+        // copy
+        if (Inst->getOperand(1).isReg()) {
+          MachineInstr *Copy = BuildMI(*MBB, Inst, DL,
+                                       get(TargetOpcode::COPY))
+                                       .addOperand(Inst->getOperand(0))
+                                       .addOperand(Inst->getOperand(1));
+          Worklist.push_back(Copy);
+        } else {
+          // Otherwise, we need to split this into two movs, because there is
+          // no 64-bit VALU move instruction.
+          unsigned LoDst, HiDst, Dst;
+          LoDst = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
+          HiDst = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
+          Dst = MRI.createVirtualRegister(
+              MRI.getRegClass(Inst->getOperand(0).getReg()));
+
+          MachineInstr *Lo = BuildMI(*MBB, Inst, DL, get(AMDGPU::S_MOV_B32),
+                                     LoDst)
+                             .addImm(Inst->getOperand(1).getImm() & 0xFFFFFFFF);
+          MachineInstr *Hi = BuildMI(*MBB, Inst, DL, get(AMDGPU::S_MOV_B32),
+                                     HiDst)
+                                    .addImm(Inst->getOperand(1).getImm() >> 32);
+
+          BuildMI(*MBB, Inst, DL, get(TargetOpcode::REG_SEQUENCE), Dst)
+                  .addReg(LoDst)
+                  .addImm(AMDGPU::sub0)
+                  .addReg(HiDst)
+                  .addImm(AMDGPU::sub1);
+
+          MRI.replaceRegWith(Inst->getOperand(0).getReg(), Dst);
+          Worklist.push_back(Lo);
+          Worklist.push_back(Hi);
+        }
+        Inst->eraseFromParent();
+        continue;
+      }
+    }
+
     unsigned NewOpcode = getVALUOp(*Inst);
     if (NewOpcode == AMDGPU::INSTRUCTION_LIST_END)
       continue;
 
-    MachineRegisterInfo &MRI = Inst->getParent()->getParent()->getRegInfo();
-
     // Use the new VALU Opcode.
     const MCInstrDesc &NewDesc = get(NewOpcode);
     Inst->setDesc(NewDesc);

Added: llvm/trunk/test/CodeGen/R600/salu-to-valu.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/salu-to-valu.ll?rev=204475&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/R600/salu-to-valu.ll (added)
+++ llvm/trunk/test/CodeGen/R600/salu-to-valu.ll Fri Mar 21 10:51:54 2014
@@ -0,0 +1,42 @@
+; RUN: llc < %s -march=r600 -mcpu=SI  | FileCheck %s
+
+; In this test both the pointer and the offset operands to the
+; BUFFER_LOAD instructions end up being stored in vgprs.  This
+; requires us to add the pointer and offset together, store the
+; result in the offset operand (vaddr), and then store 0 in an
+; sgpr register pair and use that for the pointer operand
+; (low 64-bits of srsrc).
+
+; CHECK-LABEL: @mubuf
+; Make sure we aren't using VGPRs for the source operand of S_MOV_B64
+; CHECK-NOT: S_MOV_B64 s[{{[0-9]+:[0-9]+}}], v
+define void @mubuf(i32 addrspace(1)* %out, i8 addrspace(1)* %in) {
+entry:
+  %0 = call i32 @llvm.r600.read.tidig.x() #1
+  %1 = call i32 @llvm.r600.read.tidig.y() #1
+  %2 = sext i32 %0 to i64
+  %3 = sext i32 %1 to i64
+  br label %loop
+
+loop:
+  %4 = phi i64 [0, %entry], [%5, %loop]
+  %5 = add i64 %2, %4
+  %6 = getelementptr i8 addrspace(1)* %in, i64 %5
+  %7 = load i8 addrspace(1)* %6, align 1
+  %8 = or i64 %5, 1
+  %9 = getelementptr i8 addrspace(1)* %in, i64 %8
+  %10 = load i8 addrspace(1)* %9, align 1
+  %11 = add i8 %7, %10
+  %12 = sext i8 %11 to i32
+  store i32 %12, i32 addrspace(1)* %out
+  %13 = icmp slt i64 %5, 10
+  br i1 %13, label %loop, label %done
+
+done:
+  ret void
+}
+
+declare i32 @llvm.r600.read.tidig.x() #1
+declare i32 @llvm.r600.read.tidig.y() #1
+
+attributes #1 = { nounwind readnone }





More information about the llvm-commits mailing list