1
0
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:
Dominik Montada 2020-06-10 17:15:09 +02:00
parent ecfcde54b7
commit 1fcb94df38
6 changed files with 66 additions and 3 deletions

View File

@ -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 {

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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
...

View 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
...