Skip to content

Commit 1520a50

Browse files
committed
[CodeGen]Added support for COPY_LANEMASK instruction
This new instruction takes laneMask as an operand with respect to the input operand storing the essential information.
1 parent 4c7f52d commit 1520a50

File tree

11 files changed

+132
-4
lines changed

11 files changed

+132
-4
lines changed

llvm/include/llvm/CodeGen/MachineInstr.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,8 @@ class MachineInstr
14291429
}
14301430

14311431
bool isCopy() const {
1432-
return getOpcode() == TargetOpcode::COPY;
1432+
return (getOpcode() == TargetOpcode::COPY ||
1433+
getOpcode() == TargetOpcode::COPY_LANEMASK);
14331434
}
14341435

14351436
bool isFullCopy() const {
@@ -1465,6 +1466,7 @@ class MachineInstr
14651466
case TargetOpcode::PHI:
14661467
case TargetOpcode::G_PHI:
14671468
case TargetOpcode::COPY:
1469+
case TargetOpcode::COPY_LANEMASK:
14681470
case TargetOpcode::INSERT_SUBREG:
14691471
case TargetOpcode::SUBREG_TO_REG:
14701472
case TargetOpcode::REG_SEQUENCE:

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ HANDLE_TARGET_OPCODE(REG_SEQUENCE)
114114
/// used to copy between subregisters of virtual registers.
115115
HANDLE_TARGET_OPCODE(COPY)
116116

117+
/// COPY_LANEMASK - Target-independent register copy for active mask in
118+
/// register as represented by the lanemask. This instruction can only be
119+
/// used to copy between physical registers.
120+
HANDLE_TARGET_OPCODE(COPY_LANEMASK)
121+
117122
/// BUNDLE - This instruction represents an instruction bundle. Instructions
118123
/// which immediately follow a BUNDLE instruction which are marked with
119124
/// 'InsideBundle' flag are inside the bundle.

llvm/include/llvm/Target/Target.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,13 @@ def COPY : StandardPseudoInstruction {
13291329
let isAsCheapAsAMove = true;
13301330
let hasNoSchedulingInfo = false;
13311331
}
1332+
def COPY_LANEMASK : StandardPseudoInstruction {
1333+
let OutOperandList = (outs unknown:$dst);
1334+
let InOperandList = (ins unknown:$src, unknown:$lanemask);
1335+
let AsmString = "";
1336+
let hasSideEffects = false;
1337+
let isAsCheapAsAMove = true;
1338+
}
13321339
def BUNDLE : StandardPseudoInstruction {
13331340
let OutOperandList = (outs);
13341341
let InOperandList = (ins variable_ops);

llvm/lib/CodeGen/MIRParser/MIParser.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2876,14 +2876,14 @@ bool MIParser::parseLaneMaskOperand(MachineOperand &Dest) {
28762876

28772877
lex();
28782878
if (expectAndConsume(MIToken::lparen))
2879-
return error("expected syntax lanemask(...)");
2879+
return error("lanemask should begin with '('.");
28802880

28812881
LaneBitmask LaneMask = LaneBitmask::getAll();
28822882
// Parse lanemask.
28832883
if (Token.isNot(MIToken::IntegerLiteral) && Token.isNot(MIToken::HexLiteral))
2884-
return error("expected a lane mask");
2884+
return error("expected a valid lane mask value.");
28852885
static_assert(sizeof(LaneBitmask::Type) == sizeof(uint64_t),
2886-
"Use correct get-function for lane mask");
2886+
"Use correct get-function for lane mask.");
28872887
LaneBitmask::Type V;
28882888
if (getUint64(V))
28892889
return error("invalid lanemask value");

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2414,6 +2414,34 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
24142414
}
24152415
break;
24162416
}
2417+
case TargetOpcode::COPY_LANEMASK: {
2418+
const MachineOperand &DstOp = MI->getOperand(0);
2419+
const MachineOperand &SrcOp = MI->getOperand(1);
2420+
const MachineOperand &LaneMaskOp = MI->getOperand(2);
2421+
const Register SrcReg = SrcOp.getReg();
2422+
const Register DstReg = DstOp.getReg();
2423+
const LaneBitmask LaneMask = LaneMaskOp.getLaneMask();
2424+
2425+
if (!SrcReg.isPhysical() || !DstReg.isPhysical()) {
2426+
if (!SrcReg.isPhysical()) {
2427+
report("Copy with lanemask Instruction uses virtual register", &SrcOp,
2428+
1);
2429+
}
2430+
if (!DstReg.isPhysical()) {
2431+
report("Copy with lanemask Instruction uses virtual register", &DstOp,
2432+
0);
2433+
}
2434+
break;
2435+
}
2436+
2437+
if (LaneMask.none())
2438+
report("Lanemask takes up the zero value", MI);
2439+
2440+
if (LaneMask.all())
2441+
report("Copy Instruction can be used instead of copy with lanemask", MI);
2442+
2443+
break;
2444+
}
24172445
case TargetOpcode::STATEPOINT: {
24182446
StatepointOpers SO(MI);
24192447
if (!MI->getOperand(SO.getIDPos()).isImm() ||
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# RUN: not llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -verify-machineinstrs %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
---
4+
name: test_missing_rparen
5+
tracksRegLiveness: true
6+
body: |
7+
bb.0:
8+
liveins: $vgpr0
9+
10+
; CHECK: [[@LINE+1]]:47: lanemask should be terminated by ')'.
11+
$vgpr1 = COPY_LANEMASK $vgpr0, lanemask(16
12+
S_ENDPGM 0
13+
...
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# RUN: not llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -verify-machineinstrs %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
---
4+
name: test_missing_lparen
5+
tracksRegLiveness: true
6+
body: |
7+
bb.0:
8+
liveins: $vgpr0
9+
10+
; CHECK: [[@LINE+1]]:45: lanemask should begin with '('.
11+
$vgpr1 = COPY_LANEMASK $vgpr0, lanemask 14)
12+
S_ENDPGM 0
13+
...
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# RUN: not llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -verify-machineinstrs %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
---
4+
name: test_wrong_lanemask_type
5+
tracksRegLiveness: true
6+
body: |
7+
bb.0:
8+
liveins: $vgpr0
9+
10+
; CHECK: [[@LINE+1]]:45: expected a valid lane mask value.
11+
$vgpr1 = COPY_LANEMASK $vgpr0, lanemask(undef)
12+
S_ENDPGM 0
13+
...
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -verify-machineinstrs -o - %s | FileCheck %s
2+
3+
# This test checks for the correctness of the MIR parser for lanemask
4+
5+
# CHECK-LABEL: name: test_lanemask_operand
6+
# CHECK: COPY_LANEMASK $vgpr0, lanemask(0x0000000000000020)
7+
---
8+
name: test_lanemask_operand
9+
tracksRegLiveness: true
10+
body: |
11+
bb.0:
12+
liveins: $vgpr0
13+
14+
$vgpr1 = COPY_LANEMASK $vgpr0, lanemask(32)
15+
S_ENDPGM 0
16+
...
17+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# RUN: not --crash llc -o - -mtriple=amdgcn-amd-amdhsa -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s
2+
# REQUIRES: amdgpu-registered-target
3+
4+
---
5+
name: test_copy_lanemask_instruction_0
6+
tracksRegLiveness: true
7+
body: |
8+
bb.0:
9+
liveins: $vgpr0, $vgpr1
10+
11+
$vgpr2 = COPY_LANEMASK $vgpr0, lanemask(0)
12+
$vgpr3 = COPY_LANEMASK $vgpr1, lanemask(0xFFFFFFFFFFFFFFFF)
13+
S_ENDPGM 0
14+
...

0 commit comments

Comments
 (0)