MachineVerifier: Verify REG_SEQUENCE

Somehow there was no verification of this, other than an ad-hoc
assertion in TwoAddressInstructions.
This commit is contained in:
Matt Arsenault 2022-09-21 10:42:03 -04:00
parent c2e76f914c
commit 94ebd7d9ff
7 changed files with 106 additions and 19 deletions

View File

@ -531,7 +531,7 @@ static void printFrameIndex(raw_ostream& OS, int FrameIndex, bool IsFixed,
void MachineOperand::printSubRegIdx(raw_ostream &OS, uint64_t Index,
const TargetRegisterInfo *TRI) {
OS << "%subreg.";
if (TRI)
if (TRI && Index != 0 && Index < TRI->getNumSubRegIndices())
OS << TRI->getSubRegIndexName(Index);
else
OS << Index;

View File

@ -1923,6 +1923,36 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
break;
}
} break;
case TargetOpcode::REG_SEQUENCE: {
unsigned NumOps = MI->getNumOperands();
if (!(NumOps & 1)) {
report("Invalid number of operands for REG_SEQUENCE", MI);
break;
}
for (unsigned I = 1; I != NumOps; I += 2) {
const MachineOperand &RegOp = MI->getOperand(I);
const MachineOperand &SubRegOp = MI->getOperand(I + 1);
if (!RegOp.isReg())
report("Invalid register operand for REG_SEQUENCE", &RegOp, I);
if (!SubRegOp.isImm() || SubRegOp.getImm() == 0 ||
SubRegOp.getImm() >= TRI->getNumSubRegIndices()) {
report("Invalid subregister index operand for REG_SEQUENCE",
&SubRegOp, I + 1);
}
}
Register DstReg = MI->getOperand(0).getReg();
if (DstReg.isPhysical())
report("REG_SEQUENCE does not support physical register results", MI);
if (MI->getOperand(0).getSubReg())
report("Invalid subreg result for REG_SEQUENCE", MI);
break;
}
}
}

View File

@ -1887,11 +1887,6 @@ void TwoAddressInstructionPass::
eliminateRegSequence(MachineBasicBlock::iterator &MBBI) {
MachineInstr &MI = *MBBI;
Register DstReg = MI.getOperand(0).getReg();
if (MI.getOperand(0).getSubReg() || DstReg.isPhysical() ||
!(MI.getNumOperands() & 1)) {
LLVM_DEBUG(dbgs() << "Illegal REG_SEQUENCE instruction:" << MI);
llvm_unreachable(nullptr);
}
SmallVector<Register, 4> OrigRegs;
if (LIS) {

View File

@ -51,7 +51,7 @@ body: |
%1:sgpr_64 = S_LOAD_DWORDX2_IMM %1, 36, 0 :: (dereferenceable invariant load (s64) from `i64 addrspace(4)* undef`, addrspace 4)
%2:sgpr_32 = COPY $sgpr2
%3:sgpr_32 = COPY $sgpr3
%4:sgpr_128 = REG_SEQUENCE %1, %2, %3
%4:sgpr_128 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1, %3, %subreg.sub2
%5:vgpr_32 = COPY $vgpr0
%6:vgpr_32 = COPY $vgpr1
@ -82,7 +82,7 @@ body: |
%1:sgpr_64 = S_LOAD_DWORDX2_IMM %1, 36, 0 :: (dereferenceable invariant load (s64) from `i64 addrspace(4)* undef`, addrspace 4)
%2:sgpr_32 = COPY $sgpr2
%3:sgpr_32 = COPY $sgpr3
%4:sgpr_128 = REG_SEQUENCE %1, %2, %3
%4:sgpr_128 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1, %3, %subreg.sub2
%5:vgpr_32 = COPY $vgpr0
%6:vgpr_32 = COPY $vgpr1
@ -113,7 +113,7 @@ body: |
%1:sgpr_64 = S_LOAD_DWORDX2_IMM %1, 36, 0 :: (dereferenceable invariant load (s64) from `i64 addrspace(4)* undef`, addrspace 4)
%2:sgpr_32 = COPY $sgpr2
%3:sgpr_32 = COPY $sgpr3
%4:sgpr_128 = REG_SEQUENCE %1, %2, %3
%4:sgpr_128 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1, %3, %subreg.sub2
%5:vgpr_32 = COPY $vgpr0
%6:vgpr_32 = COPY $vgpr1
@ -143,7 +143,7 @@ body: |
%1:sgpr_64 = S_LOAD_DWORDX2_IMM %1, 36, 0 :: (dereferenceable invariant load (s64) from `i64 addrspace(4)* undef`, addrspace 4)
%2:sgpr_32 = COPY $sgpr2
%3:sgpr_32 = COPY $sgpr3
%4:sgpr_128 = REG_SEQUENCE %1, %2, %3
%4:sgpr_128 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1, %3, %subreg.sub2
%5:vgpr_32 = COPY $vgpr0
%6:vgpr_32 = COPY $vgpr1

View File

@ -51,7 +51,7 @@ body: |
%1:sgpr_64 = S_LOAD_DWORDX2_IMM %1, 36, 0 :: (dereferenceable invariant load (s64) from `i64 addrspace(4)* undef`, addrspace 4)
%2:sgpr_32 = COPY $sgpr2
%3:sgpr_32 = COPY $sgpr3
%4:sgpr_128 = REG_SEQUENCE %1, %2, %3
%4:sgpr_128 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1, %3, %subreg.sub2
%5:vgpr_32 = COPY $vgpr0
%6:vgpr_32 = COPY $vgpr1
@ -82,7 +82,7 @@ body: |
%1:sgpr_64 = S_LOAD_DWORDX2_IMM %1, 36, 0 :: (dereferenceable invariant load (s64) from `i64 addrspace(4)* undef`, addrspace 4)
%2:sgpr_32 = COPY $sgpr2
%3:sgpr_32 = COPY $sgpr3
%4:sgpr_128 = REG_SEQUENCE %1, %2, %3
%4:sgpr_128 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1, %3, %subreg.sub2
%5:vgpr_32 = COPY $vgpr0
%6:vgpr_32 = COPY $vgpr1
@ -113,7 +113,7 @@ body: |
%1:sgpr_64 = S_LOAD_DWORDX2_IMM %1, 36, 0 :: (dereferenceable invariant load (s64) from `i64 addrspace(4)* undef`, addrspace 4)
%2:sgpr_32 = COPY $sgpr2
%3:sgpr_32 = COPY $sgpr3
%4:sgpr_128 = REG_SEQUENCE %1, %2, %3
%4:sgpr_128 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1, %3, %subreg.sub2
%5:vgpr_32 = COPY $vgpr0
%6:vgpr_32 = COPY $vgpr1
@ -143,7 +143,7 @@ body: |
%1:sgpr_64 = S_LOAD_DWORDX2_IMM %1, 36, 0 :: (dereferenceable invariant load (s64) from `i64 addrspace(4)* undef`, addrspace 4)
%2:sgpr_32 = COPY $sgpr2
%3:sgpr_32 = COPY $sgpr3
%4:sgpr_128 = REG_SEQUENCE %1, %2, %3
%4:sgpr_128 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1, %3, %subreg.sub2
%5:vgpr_32 = COPY $vgpr0
%6:vgpr_32 = COPY $vgpr1

View File

@ -22,13 +22,16 @@ body: |
liveins: $edi, $eax
; CHECK-LABEL: name: t
; CHECK: liveins: $edi, $eax
; CHECK: [[INSERT_SUBREG:%[0-9]+]]:gr32 = INSERT_SUBREG $edi, $al, %subreg.sub_8bit
; CHECK: [[EXTRACT_SUBREG:%[0-9]+]]:gr8 = EXTRACT_SUBREG $eax, %subreg.sub_8bit_hi
; CHECK: $ax = REG_SEQUENCE [[EXTRACT_SUBREG]], %subreg.sub_8bit, [[EXTRACT_SUBREG]], %subreg.sub_8bit_hi
; CHECK: RET64 $ax
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:gr32 = INSERT_SUBREG $edi, $al, %subreg.sub_8bit
; CHECK-NEXT: [[EXTRACT_SUBREG:%[0-9]+]]:gr8 = EXTRACT_SUBREG $eax, %subreg.sub_8bit_hi
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:gr8 = REG_SEQUENCE [[EXTRACT_SUBREG]], %subreg.sub_8bit, [[EXTRACT_SUBREG]], %subreg.sub_8bit_hi
; CHECK-NEXT: $ax = COPY [[REG_SEQUENCE]]
; CHECK-NEXT: RET64 $ax
%0 = INSERT_SUBREG $edi, $al, %subreg.sub_8bit
%1 = EXTRACT_SUBREG $eax, %subreg.sub_8bit_hi
$ax = REG_SEQUENCE %1, %subreg.sub_8bit, %1, %subreg.sub_8bit_hi
%2:gr8 = REG_SEQUENCE %1, %subreg.sub_8bit, %1, %subreg.sub_8bit_hi
$ax = COPY %2
RET64 $ax
...

View File

@ -0,0 +1,59 @@
# REQUIRES: amdgpu-registered-target
# RUN: not --crash llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -run-pass=none -o /dev/null %s 2>&1 | FileCheck %s
---
name: invalid_reg_sequence
tracksRegLiveness: true
body: |
bb.0:
%0:vgpr_32 = IMPLICIT_DEF
%1:vgpr_32 = IMPLICIT_DEF
; No operands
; CHECK: *** Bad machine code: Too few operands ***
REG_SEQUENCE
; Only dest operand
; CHECK: *** Bad machine code: Too few operands ***
%2:vreg_64 = REG_SEQUENCE
; Missing destination
; CHECK: *** Bad machine code: Explicit definition marked as use ***
REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
; Missing subreg operand
; CHECK: *** Bad machine code: Invalid number of operands for REG_SEQUENCE ***
%3:vreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1
; Missing register operand
; CHECK: *** Bad machine code: Invalid number of operands for REG_SEQUENCE ***
%4:vreg_64 = REG_SEQUENCE %0, %subreg.sub0, %subreg.sub1
; Physreg destination
; CHECK: *** Bad machine code: REG_SEQUENCE does not support physical register results ***
$vgpr0_vgpr1 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
; Subreg in destination
; CHECK: *** Bad machine code: Invalid subreg result for REG_SEQUENCE ***
%5.sub0_sub1:vreg_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
; All operands are registers
; CHECK: *** Bad machine code: Invalid subregister index operand for REG_SEQUENCE ***
%6:vreg_64 = REG_SEQUENCE %0, %1
; Register and subreg index operand order swapped
; CHECK: *** Bad machine code: Invalid register operand for REG_SEQUENCE ***
; CHECK: *** Bad machine code: Invalid subregister index operand for REG_SEQUENCE ***
%7:vreg_64 = REG_SEQUENCE %subreg.sub0, %0, %subreg.sub1, %1
; Invalid subreg index constants
; CHECK: *** Bad machine code: Invalid subregister index operand for REG_SEQUENCE ***
; CHECK: - instruction: %8:vreg_64 = REG_SEQUENCE %0:vgpr_32, %subreg.0, %1:vgpr_32, %subreg.99999
; CHECK-NEXT: operand 2: 0
; CHECK: *** Bad machine code: Invalid subregister index operand for REG_SEQUENCE ***
; CHECK: instruction: %8:vreg_64 = REG_SEQUENCE %0:vgpr_32, %subreg.0, %1:vgpr_32, %subreg.99999
; CHECK-NEXT: operand 4: 99999
%8:vreg_64 = REG_SEQUENCE %0, 0, %1, 99999
...