Index: lib/Target/AMDGPU/SIISelLowering.cpp =================================================================== --- lib/Target/AMDGPU/SIISelLowering.cpp +++ lib/Target/AMDGPU/SIISelLowering.cpp @@ -131,6 +131,7 @@ setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); setOperationAction(ISD::BRCOND, MVT::Other, Custom); + setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Legal); for (MVT VT : MVT::integer_valuetypes()) { if (VT == MVT::i64) Index: lib/Target/AMDGPU/SIInstrInfo.td =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.td +++ lib/Target/AMDGPU/SIInstrInfo.td @@ -961,23 +961,31 @@ } } -multiclass SMRD_Inval { - let hasSideEffects = 1, mayStore = 1 in { - def "" : SMRD_Pseudo ; +multiclass SMRD_Special pattern = []> { + let hasSideEffects = 1 in { + def "" : SMRD_Pseudo ; let sbase = 0, offset = 0 in { let sdst = 0 in { - def _si : SMRD_Real_si ; + def _si : SMRD_Real_si ; } let glc = 0, sdata = 0 in { - def _vi : SMRD_Real_vi ; + def _vi : SMRD_Real_vi ; } } } } +multiclass SMRD_Inval { + let mayStore = 1 in { + defm : SMRD_Special; + } +} + class SMEM_Inval op, string opName, SDPatternOperator node> : SMRD_Real_vi { let hasSideEffects = 1; Index: lib/Target/AMDGPU/SIInstructions.td =================================================================== --- lib/Target/AMDGPU/SIInstructions.td +++ lib/Target/AMDGPU/SIInstructions.td @@ -88,7 +88,15 @@ smrd<0x0c>, "s_buffer_load_dwordx16", SReg_128, SReg_512 >; -//def S_MEMTIME : SMRD_ <0x0000001e, "s_memtime", []>; +// TODO: The finalizer implements the HSAIL clock instruction with +// s_memtime, except on VI where s_memrealtime is used. Should +// readcyclecounter be treated the same way? + +let LGKM_CNT = 0 in { +defm S_MEMTIME : SMRD_Special , "s_memtime", + (outs SReg_64:$dst), " $dst", [(set i64:$dst, (readcyclecounter))] +>; +} // let LGKM_CNT = 0 defm S_DCACHE_INV : SMRD_Inval , "s_dcache_inv", int_amdgcn_s_dcache_inv>; Index: test/CodeGen/AMDGPU/readcyclecounter.ll =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/readcyclecounter.ll @@ -0,0 +1,22 @@ +; RUN: llc -march=amdgcn -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=GCN %s +; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=VI -check-prefix=GCN %s + +declare i64 @llvm.readcyclecounter() #0 + +; GCN-LABEL: {{^}}test_readcyclecounter: +; GCN: s_memtime s{{\[[0-9]+:[0-9]+\]}} +; GCN: buffer_store_dwordx2 +; GCN-NOT: lgkmcnt +; GCN: s_memtime s{{\[[0-9]+:[0-9]+\]}} +; GCN-NOT: lgkmcnt +; GCN: buffer_store_dwordx2 +define void @test_readcyclecounter(i64 addrspace(1)* %out) #0 { + %cycle0 = call i64 @llvm.readcyclecounter() + store volatile i64 %cycle0, i64 addrspace(1)* %out + + %cycle1 = call i64 @llvm.readcyclecounter() + store volatile i64 %cycle1, i64 addrspace(1)* %out + ret void +} + +attributes #0 = { nounwind } Index: test/MC/AMDGPU/smrd.s =================================================================== --- test/MC/AMDGPU/smrd.s +++ test/MC/AMDGPU/smrd.s @@ -67,3 +67,6 @@ s_dcache_inv_vol // CI: s_dcache_inv_vol ; encoding: [0x00,0x00,0x40,0xc7] // NOSI: error: instruction not supported on this GPU + +s_memtime s[0:1] +// GCN: s_memtime s[0:1] ; encoding: [0x00,0x00,0x80,0xc7]