diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -3822,11 +3822,7 @@ ++ConstantBusCount; SmallVector SGPRsUsed; - Register SGPRUsed = findImplicitSGPRRead(MI); - if (SGPRUsed != AMDGPU::NoRegister) { - ++ConstantBusCount; - SGPRsUsed.push_back(SGPRUsed); - } + Register SGPRUsed; for (int OpIdx : OpIndices) { if (OpIdx == -1) @@ -3835,8 +3831,8 @@ if (usesConstantBus(MRI, MO, MI.getDesc().OpInfo[OpIdx])) { if (MO.isReg()) { SGPRUsed = MO.getReg(); - if (llvm::all_of(SGPRsUsed, [this, SGPRUsed](unsigned SGPR) { - return !RI.regsOverlap(SGPRUsed, SGPR); + if (llvm::all_of(SGPRsUsed, [SGPRUsed](unsigned SGPR) { + return SGPRUsed != SGPR; })) { ++ConstantBusCount; SGPRsUsed.push_back(SGPRUsed); @@ -3847,6 +3843,18 @@ } } } + + SGPRUsed = findImplicitSGPRRead(MI); + if (SGPRUsed != AMDGPU::NoRegister) { + // Implicit uses may safely overlap true overands + if (llvm::all_of(SGPRsUsed, [this, SGPRUsed](unsigned SGPR) { + return !RI.regsOverlap(SGPRUsed, SGPR); + })) { + ++ConstantBusCount; + SGPRsUsed.push_back(SGPRUsed); + } + } + // v_writelane_b32 is an exception from constant bus restriction: // vsrc0 can be sgpr, const or m0 and lane select sgpr, m0 or inline-const if (ConstantBusCount > ST.getConstantBusLimit(Opcode) && diff --git a/llvm/test/CodeGen/AMDGPU/verify-constant-bus-violations.mir b/llvm/test/CodeGen/AMDGPU/verify-constant-bus-violations.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/verify-constant-bus-violations.mir @@ -0,0 +1,27 @@ +# RUN: not --crash llc -march=amdgcn -mcpu=gfx900 -run-pass machineverifier -o /dev/null %s 2>&1 | FileCheck -check-prefix=GFX9-ERR %s +# RUN: not --crash llc -march=amdgcn -mcpu=gfx1010 -mattr=-wavefrontsize32,+wavefrontsize64 -run-pass machineverifier -o /dev/null %s 2>&1 | FileCheck -check-prefix=GFX10-ERR %s + +# GFX9-ERR: *** Bad machine code: VOP* instruction violates constant bus restriction *** +# GFX9-ERR: $vgpr0 = V_CNDMASK_B32_e64 0, $sgpr0, 0, -1, killed $sgpr0_sgpr1, implicit $exec +--- +name: sgpr_reuse_2sgpr +liveins: + - { reg: '$sgpr0_sgpr1', virtual-reg: '' } +body: | + bb.0: + liveins: $sgpr0_sgpr1 + $vgpr0 = V_CNDMASK_B32_e64 0, $sgpr0, 0, -1, killed $sgpr0_sgpr1, implicit $exec +... + +# GFX10-ERR: *** Bad machine code: VOP* instruction violates constant bus restriction *** +# GFX10-ERR: $vgpr0 = V_CNDMASK_B32_e64 0, $sgpr0, 0, $sgpr2, killed $sgpr0_sgpr1, implicit $exec +--- +name: sgpr_reuse_3sgpr +liveins: + - { reg: '$sgpr0_sgpr1', virtual-reg: '' } + - { reg: '$sgpr2', virtual-reg: '' } +body: | + bb.0: + liveins: $sgpr0_sgpr1, $sgpr2 + $vgpr0 = V_CNDMASK_B32_e64 0, $sgpr0, 0, $sgpr2, killed $sgpr0_sgpr1, implicit $exec +...