Skip to content

Commit 0381932

Browse files
shiltianyanyao-wang
authored andcommitted
[AMDGPU][AsmParser] Allow v_writelane_b32 to use SGPR and M0 as source operands at the same time (llvm#78827)
Currently the asm parser takes `v_writelane_b32 v1, s13, m0` as illegal instruction for pre-gfx11 because it uses two constant buses while the hardware can only allow one. However, based on the comment of `AMDGPUInstructionSelector::selectWritelane`, it is allowed to have M0 as lane selector and a SGPR used as SRC0 because the lane selector doesn't count as a use of constant bus. In fact, codegen can already generate this form, but this inconsistency is not exposed because the validation of constant bus limitation only happens when paring an assembly but we don't have a test case when both SGPR and M0 used as source operands for the instruction. Change-Id: I22b1548775f3c34472657134541f4ea40bfdc9e3
1 parent 7db7f5e commit 0381932

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3389,6 +3389,24 @@ bool AMDGPUAsmParser::usesConstantBus(const MCInst &Inst, unsigned OpIdx) {
33893389
}
33903390
}
33913391

3392+
// Based on the comment for `AMDGPUInstructionSelector::selectWritelane`:
3393+
// Writelane is special in that it can use SGPR and M0 (which would normally
3394+
// count as using the constant bus twice - but in this case it is allowed since
3395+
// the lane selector doesn't count as a use of the constant bus). However, it is
3396+
// still required to abide by the 1 SGPR rule.
3397+
static bool checkWriteLane(const MCInst &Inst) {
3398+
const unsigned Opcode = Inst.getOpcode();
3399+
if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3400+
return false;
3401+
const MCOperand &LaneSelOp = Inst.getOperand(2);
3402+
if (!LaneSelOp.isReg())
3403+
return false;
3404+
auto LaneSelReg = mc2PseudoReg(LaneSelOp.getReg());
3405+
if (LaneSelReg == M0 || LaneSelReg == M0_gfxpre11)
3406+
return true;
3407+
return false;
3408+
}
3409+
33923410
bool AMDGPUAsmParser::validateConstantBusLimitations(
33933411
const MCInst &Inst, const OperandVector &Operands) {
33943412
const unsigned Opcode = Inst.getOpcode();
@@ -3404,6 +3422,9 @@ bool AMDGPUAsmParser::validateConstantBusLimitations(
34043422
!isVOPD(Opcode))
34053423
return true;
34063424

3425+
if (checkWriteLane(Inst))
3426+
return true;
3427+
34073428
// Check special imm operands (used by madmk, etc)
34083429
if (AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::imm)) {
34093430
++NumLiterals;

llvm/test/MC/AMDGPU/writelane_m0.s

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: llvm-mc --triple=amdgcn --mcpu=gfx600 -show-encoding %s | FileCheck %s -check-prefix=GFX6
2+
// RUN: llvm-mc --triple=amdgcn --mcpu=gfx700 -show-encoding %s | FileCheck %s -check-prefix=GFX7
3+
// RUN: llvm-mc --triple=amdgcn --mcpu=gfx904 -show-encoding %s | FileCheck %s -check-prefix=GFX9
4+
// RUN: llvm-mc --triple=amdgcn --mcpu=gfx940 -show-encoding %s | FileCheck %s -check-prefix=GFX9
5+
// RUN: llvm-mc --triple=amdgcn --mcpu=gfx1010 -show-encoding %s | FileCheck %s -check-prefix=GFX10
6+
// RUN: llvm-mc --triple=amdgcn --mcpu=gfx1030 -show-encoding %s | FileCheck %s -check-prefix=GFX10
7+
// RUN: llvm-mc --triple=amdgcn --mcpu=gfx1100 -show-encoding %s | FileCheck %s -check-prefix=GFX11
8+
9+
.text
10+
v_writelane_b32 v1, s13, m0
11+
12+
// GFX6: v_writelane_b32 v1, s13, m0 ; encoding: [0x0d,0xf8,0x02,0x04]
13+
// GFX7: v_writelane_b32 v1, s13, m0 ; encoding: [0x0d,0xf8,0x02,0x04]
14+
// GFX9: v_writelane_b32 v1, s13, m0 ; encoding: [0x01,0x00,0x8a,0xd2,0x0d,0xf8,0x00,0x00]
15+
// GFX10: v_writelane_b32 v1, s13, m0 ; encoding: [0x01,0x00,0x61,0xd7,0x0d,0xf8,0x00,0x00]
16+
// GFX11: v_writelane_b32 v1, s13, m0 ; encoding: [0x01,0x00,0x61,0xd7,0x0d,0xfa,0x00,0x00]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx600 -verify-machineinstrs -run-pass=none -o - %s | FileCheck %s
2+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx700 -verify-machineinstrs -run-pass=none -o - %s | FileCheck %s
3+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx904 -verify-machineinstrs -run-pass=none -o - %s | FileCheck %s
4+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx940 -verify-machineinstrs -run-pass=none -o - %s | FileCheck %s
5+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1010 -verify-machineinstrs -run-pass=none -o - %s | FileCheck %s
6+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1030 -verify-machineinstrs -run-pass=none -o - %s | FileCheck %s
7+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -verify-machineinstrs -run-pass=none -o - %s | FileCheck %s
8+
9+
---
10+
11+
name: writelane_m0
12+
body: |
13+
bb.0:
14+
; CHECK: $vgpr0 = V_WRITELANE_B32 $sgpr0, $m0, $vgpr0
15+
$vgpr0 = V_WRITELANE_B32 $sgpr0, $m0, $vgpr0

0 commit comments

Comments
 (0)