mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 19:12:56 +02:00
[MachineVerifier][GlobalISel] Check that branches have a MBB operand or are declared indirect. Add missing properties to G_BRJT, G_BRINDIRECT
Summary: Teach MachineVerifier to check branches for MBB operands if they are not declared indirect. Add `isBarrier`, `isIndirectBranch` to `G_BRINDIRECT` and `G_BRJT`. Without these, `MachineInstr.isConditionalBranch()` was giving a false-positive for those instructions. Reviewers: aemerson, qcolombet, dsanders, arsenm Reviewed By: dsanders Subscribers: hiraditya, wdng, simoncook, s.egerton, arsenm, rovka, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D81587
This commit is contained in:
parent
ecfcde54b7
commit
1fcb94df38
@ -1085,6 +1085,8 @@ def G_BRINDIRECT : GenericInstruction {
|
||||
let hasSideEffects = 0;
|
||||
let isBranch = 1;
|
||||
let isTerminator = 1;
|
||||
let isBarrier = 1;
|
||||
let isIndirectBranch = 1;
|
||||
}
|
||||
|
||||
// Generic branch to jump table entry
|
||||
@ -1094,6 +1096,8 @@ def G_BRJT : GenericInstruction {
|
||||
let hasSideEffects = 0;
|
||||
let isBranch = 1;
|
||||
let isTerminator = 1;
|
||||
let isBarrier = 1;
|
||||
let isIndirectBranch = 1;
|
||||
}
|
||||
|
||||
def G_READ_REGISTER : GenericInstruction {
|
||||
|
@ -863,6 +863,22 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
|
||||
const MCInstrDesc &MCID = MI->getDesc();
|
||||
unsigned NumOps = MI->getNumOperands();
|
||||
|
||||
// Branches must reference a basic block if they are not indirect
|
||||
if (MI->isBranch() && !MI->isIndirectBranch()) {
|
||||
bool HasMBB = false;
|
||||
for (const MachineOperand &Op : MI->operands()) {
|
||||
if (Op.isMBB()) {
|
||||
HasMBB = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!HasMBB)
|
||||
report("Branch instruction is missing a basic block operand or "
|
||||
"isIndirectBranch property",
|
||||
MI);
|
||||
}
|
||||
|
||||
// Check types.
|
||||
SmallVector<LLT, 4> Types;
|
||||
for (unsigned I = 0, E = std::min(MCID.getNumOperands(), NumOps);
|
||||
|
@ -25,7 +25,6 @@ registers:
|
||||
body: |
|
||||
; CHECK-LABEL: name: test_blockaddress
|
||||
; CHECK: bb.0 (%ir-block.0):
|
||||
; CHECK: successors: %bb.1(0x80000000)
|
||||
; CHECK: [[BLOCK_ADDR:%[0-9]+]]:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
|
||||
; CHECK: [[ADRP:%[0-9]+]]:gpr64(p0) = ADRP target-flags(aarch64-page) @addr
|
||||
; CHECK: [[ADD_LOW:%[0-9]+]]:_(p0) = G_ADD_LOW [[ADRP]](p0), target-flags(aarch64-pageoff, aarch64-nc) @addr
|
||||
|
@ -30,7 +30,6 @@ registers:
|
||||
body: |
|
||||
; CHECK-LABEL: name: test_blockaddress
|
||||
; CHECK: bb.0 (%ir-block.0):
|
||||
; CHECK: successors: %bb.1(0x80000000)
|
||||
; CHECK: [[MOVaddrBA:%[0-9]+]]:gpr64 = MOVaddrBA target-flags(aarch64-page) blockaddress(@test_blockaddress, %ir-block.block), target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block)
|
||||
; CHECK: [[MOVaddr:%[0-9]+]]:gpr64common = MOVaddr target-flags(aarch64-page) @addr, target-flags(aarch64-pageoff, aarch64-nc) @addr
|
||||
; CHECK: STRXui [[MOVaddrBA]], [[MOVaddr]], 0 :: (store 8 into @addr)
|
||||
@ -39,7 +38,6 @@ body: |
|
||||
; CHECK: RET_ReallyLR
|
||||
; LARGE-LABEL: name: test_blockaddress
|
||||
; LARGE: bb.0 (%ir-block.0):
|
||||
; LARGE: successors: %bb.1(0x80000000)
|
||||
; LARGE: [[MOVZXi:%[0-9]+]]:gpr64 = MOVZXi target-flags(aarch64-g0, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 0
|
||||
; LARGE: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[MOVZXi]], target-flags(aarch64-g1, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 16
|
||||
; LARGE: [[MOVKXi1:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi]], target-flags(aarch64-g2, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 32
|
||||
|
@ -0,0 +1,20 @@
|
||||
# RUN: llc -march=riscv32 -o - -run-pass=none -verify-machineinstrs %s | FileCheck %s
|
||||
# REQUIRES: global-isel, riscv-registered-target
|
||||
|
||||
# This test checks that the G_BRINDIRECT is an indirect branch by leveraging
|
||||
# RISCV's version of analyzeBranch. If G_BRINDIRECT would not be an indirect
|
||||
# branch, this test would crash.
|
||||
|
||||
---
|
||||
name: test_indirect_branch
|
||||
legalized: true
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $x0
|
||||
%0:_(p0) = COPY $x0
|
||||
|
||||
; CHECK-NOT: Branch instruction is missing a basic block operand or isIndirectBranch property
|
||||
G_BRINDIRECT %0
|
||||
|
||||
...
|
26
test/MachineVerifier/test_g_brjt_is_indirect_branch.mir
Normal file
26
test/MachineVerifier/test_g_brjt_is_indirect_branch.mir
Normal file
@ -0,0 +1,26 @@
|
||||
# RUN: llc -march=riscv32 -o - -run-pass=none -verify-machineinstrs %s | FileCheck %s
|
||||
# REQUIRES: global-isel, riscv-registered-target
|
||||
|
||||
# This test checks that the G_BRJT is an indirect branch by leveraging RISCV's
|
||||
# version of analyzeBranch. If G_BRJT would not be an indirect branch, this
|
||||
# test would crash.
|
||||
|
||||
---
|
||||
name: test_jump_table
|
||||
legalized: true
|
||||
tracksRegLiveness: true
|
||||
jumpTable:
|
||||
kind: block-address
|
||||
entries:
|
||||
- id: 0
|
||||
blocks: [ '%bb.0' ]
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $x0
|
||||
%0:_(s32) = COPY $x0
|
||||
%1:_(p0) = COPY $x0
|
||||
|
||||
; CHECK-NOT: Branch instruction is missing a basic block operand or isIndirectBranch property
|
||||
G_BRJT %1, %jump-table.0, %0
|
||||
|
||||
...
|
Loading…
Reference in New Issue
Block a user