-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[CodeGen] Add MO_LaneMask type and a new COPY_LANEMASK instruction #151944
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1a5cf77
9964fea
a6c83a0
69ff971
c8c40d2
67cd29f
238f2a3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -496,6 +496,7 @@ class MIParser { | |
bool parseTargetIndexOperand(MachineOperand &Dest); | ||
bool parseDbgInstrRefOperand(MachineOperand &Dest); | ||
bool parseCustomRegisterMaskOperand(MachineOperand &Dest); | ||
bool parseLaneMaskOperand(MachineOperand &Dest); | ||
bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest); | ||
bool parseMachineOperand(const unsigned OpCode, const unsigned OpIdx, | ||
MachineOperand &Dest, | ||
|
@@ -2870,6 +2871,32 @@ bool MIParser::parseCustomRegisterMaskOperand(MachineOperand &Dest) { | |
return false; | ||
} | ||
|
||
bool MIParser::parseLaneMaskOperand(MachineOperand &Dest) { | ||
assert(Token.is(MIToken::kw_lanemask)); | ||
|
||
lex(); | ||
|
||
if (expectAndConsume(MIToken::lparen)) | ||
return error("lanemask should begin with '('."); | ||
|
||
LaneBitmask LaneMask = LaneBitmask::getAll(); | ||
// Parse lanemask. | ||
if (Token.isNot(MIToken::IntegerLiteral) && Token.isNot(MIToken::HexLiteral)) | ||
return error("expected a valid lane mask value."); | ||
static_assert(sizeof(LaneBitmask::Type) == sizeof(uint64_t), | ||
"Use correct get-function for lane mask."); | ||
LaneBitmask::Type V; | ||
if (getUint64(V)) | ||
return error("invalid lanemask value"); | ||
LaneMask = LaneBitmask(V); | ||
lex(); | ||
|
||
if (expectAndConsume(MIToken::rparen)) | ||
return error("lanemask should be terminated by ')'."); | ||
|
||
Dest = MachineOperand::CreateLaneMask(LaneMask); | ||
return false; | ||
} | ||
|
||
bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) { | ||
assert(Token.is(MIToken::kw_liveout)); | ||
uint32_t *Mask = MF.allocateRegMask(); | ||
|
@@ -2970,6 +2997,8 @@ bool MIParser::parseMachineOperand(const unsigned OpCode, const unsigned OpIdx, | |
return parseIntrinsicOperand(Dest); | ||
case MIToken::kw_target_index: | ||
return parseTargetIndexOperand(Dest); | ||
case MIToken::kw_lanemask: | ||
return parseLaneMaskOperand(Dest); | ||
case MIToken::kw_liveout: | ||
return parseLiveoutRegisterMaskOperand(Dest); | ||
case MIToken::kw_floatpred: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2414,6 +2414,38 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { | |
} | ||
break; | ||
} | ||
case TargetOpcode::COPY_LANEMASK: { | ||
const MachineOperand &DstOp = MI->getOperand(0); | ||
const MachineOperand &SrcOp = MI->getOperand(1); | ||
const MachineOperand &LaneMaskOp = MI->getOperand(2); | ||
const Register SrcReg = SrcOp.getReg(); | ||
const LaneBitmask LaneMask = LaneMaskOp.getLaneMask(); | ||
LaneBitmask SrcMaxLanemask = LaneBitmask::getAll(); | ||
|
||
if (DstOp.getSubReg()) | ||
report("COPY_LANEMASK must not use a subregister index", &DstOp, 0); | ||
|
||
if (SrcOp.getSubReg()) | ||
report("COPY_LANEMASK must not use a subregister index", &SrcOp, 1); | ||
|
||
if (LaneMask.none()) | ||
report("COPY_LANEMASK must read at least one lane", MI); | ||
|
||
if (SrcReg.isPhysical()) { | ||
|
||
const TargetRegisterClass *SrcRC = TRI->getMinimalPhysRegClass(SrcReg); | ||
if (SrcRC) | ||
SrcMaxLanemask = SrcRC->getLaneMask(); | ||
} else { | ||
SrcMaxLanemask = MRI->getMaxLaneMaskForVReg(SrcReg); | ||
} | ||
|
||
// If LaneMask is equal to OR greater than the SrcMaxLanemask, it | ||
// impliess COPY_LANEMASK is trying to copy all lanes. | ||
if (SrcMaxLanemask <= LaneMask) | ||
report("COPY_LANEMASK cannot read all lanes", MI); | ||
|
||
break; | ||
} | ||
case TargetOpcode::STATEPOINT: { | ||
StatepointOpers SO(MI); | ||
if (!MI->getOperand(SO.getIDPos()).isImm() || | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# RUN: not llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -filetype=null %s 2>&1 | FileCheck %s | ||
|
||
--- | ||
name: test_missing_rparen | ||
tracksRegLiveness: true | ||
body: | | ||
bb.0: | ||
liveins: $vgpr0 | ||
|
||
; CHECK: [[@LINE+1]]:47: lanemask should be terminated by ')'. | ||
$vgpr1 = COPY_LANEMASK $vgpr0, lanemask(16 | ||
S_ENDPGM 0 | ||
... |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# RUN: not llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -filetype=null %s 2>&1 | FileCheck %s | ||
|
||
--- | ||
name: test_missing_lparen | ||
tracksRegLiveness: true | ||
body: | | ||
bb.0: | ||
liveins: $vgpr0 | ||
|
||
; CHECK: [[@LINE+1]]:45: lanemask should begin with '('. | ||
$vgpr1 = COPY_LANEMASK $vgpr0, lanemask 14) | ||
S_ENDPGM 0 | ||
... |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# RUN: not llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -filetype=null %s 2>&1 | FileCheck %s | ||
|
||
--- | ||
name: test_wrong_lanemask_type | ||
tracksRegLiveness: true | ||
body: | | ||
bb.0: | ||
liveins: $vgpr0 | ||
|
||
; CHECK: [[@LINE+1]]:45: expected a valid lane mask value. | ||
$vgpr1 = COPY_LANEMASK $vgpr0, lanemask(undef) | ||
S_ENDPGM 0 | ||
... |
Uh oh!
There was an error while loading. Please reload this page.