diff --git a/lib/Target/R600/SIDefines.h b/lib/Target/R600/SIDefines.h index 572ed6ae16a..f5445ad759e 100644 --- a/lib/Target/R600/SIDefines.h +++ b/lib/Target/R600/SIDefines.h @@ -13,7 +13,8 @@ namespace SIInstrFlags { enum { - MIMG = 1 << 3 + MIMG = 1 << 3, + SMRD = 1 << 4 }; } diff --git a/lib/Target/R600/SIInsertWaits.cpp b/lib/Target/R600/SIInsertWaits.cpp index ba202e3cbf6..7e42fb777d4 100644 --- a/lib/Target/R600/SIInsertWaits.cpp +++ b/lib/Target/R600/SIInsertWaits.cpp @@ -134,14 +134,19 @@ Counters SIInsertWaits::getHwCounts(MachineInstr &MI) { // LGKM may uses larger values if (TSFlags & SIInstrFlags::LGKM_CNT) { - MachineOperand &Op = MI.getOperand(0); - if (!Op.isReg()) - Op = MI.getOperand(1); - assert(Op.isReg() && "First LGKM operand must be a register!"); + if (TII->isSMRD(MI.getOpcode())) { - unsigned Reg = Op.getReg(); - unsigned Size = TRI->getMinimalPhysRegClass(Reg)->getSize(); - Result.Named.LGKM = Size > 4 ? 2 : 1; + MachineOperand &Op = MI.getOperand(0); + assert(Op.isReg() && "First LGKM operand must be a register!"); + + unsigned Reg = Op.getReg(); + unsigned Size = TRI->getMinimalPhysRegClass(Reg)->getSize(); + Result.Named.LGKM = Size > 4 ? 2 : 1; + + } else { + // DS + Result.Named.LGKM = 1; + } } else { Result.Named.LGKM = 0; diff --git a/lib/Target/R600/SIInstrFormats.td b/lib/Target/R600/SIInstrFormats.td index cd1bbcd670e..9576c055b48 100644 --- a/lib/Target/R600/SIInstrFormats.td +++ b/lib/Target/R600/SIInstrFormats.td @@ -18,11 +18,13 @@ class InstSI pattern> : field bits<1> EXP_CNT = 0; field bits<1> LGKM_CNT = 0; field bits<1> MIMG = 0; + field bits<1> SMRD = 0; let TSFlags{0} = VM_CNT; let TSFlags{1} = EXP_CNT; let TSFlags{2} = LGKM_CNT; let TSFlags{3} = MIMG; + let TSFlags{4} = SMRD; } class Enc32 pattern> : @@ -142,6 +144,7 @@ class SMRD op, bits<1> imm, dag outs, dag ins, string asm, let Inst{31-27} = 0x18; //encoding let LGKM_CNT = 1; + let SMRD = 1; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/R600/SIInstrInfo.cpp b/lib/Target/R600/SIInstrInfo.cpp index 9bb4ad9abc5..2719ea2490e 100644 --- a/lib/Target/R600/SIInstrInfo.cpp +++ b/lib/Target/R600/SIInstrInfo.cpp @@ -229,6 +229,10 @@ int SIInstrInfo::isMIMG(uint16_t Opcode) const { return get(Opcode).TSFlags & SIInstrFlags::MIMG; } +int SIInstrInfo::isSMRD(uint16_t Opcode) const { + return get(Opcode).TSFlags & SIInstrFlags::SMRD; +} + //===----------------------------------------------------------------------===// // Indirect addressing callbacks //===----------------------------------------------------------------------===// diff --git a/lib/Target/R600/SIInstrInfo.h b/lib/Target/R600/SIInstrInfo.h index 8d24ab4bf14..87b80633a0a 100644 --- a/lib/Target/R600/SIInstrInfo.h +++ b/lib/Target/R600/SIInstrInfo.h @@ -48,6 +48,7 @@ public: virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const; int isMIMG(uint16_t Opcode) const; + int isSMRD(uint16_t Opcode) const; virtual int getIndirectIndexBegin(const MachineFunction &MF) const; diff --git a/test/CodeGen/R600/local-memory.ll b/test/CodeGen/R600/local-memory.ll index 5458fb90573..9ebb7692a68 100644 --- a/test/CodeGen/R600/local-memory.ll +++ b/test/CodeGen/R600/local-memory.ll @@ -13,7 +13,7 @@ ; SI-CHECK-NEXT: .long 32768 ; EG-CHECK: LDS_WRITE -; SI-CHECK: DS_WRITE_B32 +; SI-CHECK: DS_WRITE_B32 0 ; GROUP_BARRIER must be the last instruction in a clause ; EG-CHECK: GROUP_BARRIER @@ -21,7 +21,7 @@ ; SI-CHECK: S_BARRIER ; EG-CHECK: LDS_READ_RET -; SI-CHECK: DS_READ_B32 +; SI-CHECK: DS_READ_B32 {{VGPR[0-9]+}}, 0 define void @local_memory(i32 addrspace(1)* %out) { entry: