forked from OSchip/llvm-project
MachineVerifier: Verify REG_SEQUENCE
Somehow there was no verification of this, other than an ad-hoc assertion in TwoAddressInstructions.
This commit is contained in:
parent
c2e76f914c
commit
94ebd7d9ff
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
...
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
...
|
Loading…
Reference in New Issue