[PATCH] D76961: [BranchFolder] don't remove MBB's that have their address taken
Nick Desaulniers via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 30 14:11:40 PDT 2020
nickdesaulniers added a comment.
In D76961#1950390 <https://reviews.llvm.org/D76961#1950390>, @nickdesaulniers wrote:
> 1. implement separate machine verifier checks for:
> 1. all `MachineBasicBlocks` with `INLINEASM_BR` terminators should have the targets of the `INLINEASM_BR` in their list of successors.
Ok, so I don't think this is generally the case, as we could have a `MachineOperand` to the `INLINEASM_BR` that is a `blockaddress`, yet is not a successor; when inline asm passes the address of a label ("computed goto") as input to an asm statement, but not in the label list, that doesn't make a it valid branch target (though theoretically, the inline asm could still jump to it, which is super undefined).
But with a basic check:
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 72da33c92346..94b1bd31a4e9 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -887,6 +887,17 @@ void MachineVerifier::verifyInlineAsm(const MachineInstr *MI) {
if (!MO.isReg() || !MO.isImplicit())
report("Expected implicit register after groups", &MO, OpNo);
}
+
+ if (MI->getOpcode() == TargetOpcode::INLINEASM_BR) {
+ // Check that the targets are listed as successors to this MI's parent MBB.
+ SmallPtrSet<const BasicBlock*, 2> successors;
+ for (const MachineBasicBlock* MBB : MI->getParent()->successors())
+ successors.insert(MBB->getBasicBlock());
+ for (const MachineOperand& MO : MI->operands())
+ if (MO.isBlockAddress())
+ if (!successors.count(MO.getBlockAddress()->getBasicBlock()))
+ report("Expected INLINEASM_BR blockaddress operand not in successor list of parent MBB", MI);
+ }
}
This fails on our test suite in `llvm/test/CodeGen/X86/callbr-asm-outputs.ll`'s first test case. Right off the bat, I can see we messed this up in ISEL:
# *** IR Dump After Finalize ISel and expand pseudo-instructions ***:
...
bb.0.entry:
successors: %bb.3(0x80000000); %bb.3(100.00%)
...
INLINEASM_BR &"xorl $1, $0; jmp ${2:l}" [attdialect], $0:[regdef:GR32], def %2:gr32, $1:[reguse:GR32], %3:gr32, $2:[imm], blockaddress(@test1, %ir-block.abnormal), $3:[clobber], implicit-def early-clobber $df, $4:[clobber], implicit-def early-clobber $fpsw, $5:[clobber], implicit-def early-clobber $eflags
bb.3.entry:
; predecessors: %bb.0
...
bb.2.abnormal (address-taken):
; predecessors: %bb.3
...
We can see we have an `INLINEASM_BR` `MachineInstr` with a `blockaddress` `MachineOperand`, but the parent `MachineBasicBlock` (`bb.0`) of the `INLINEASM_BR` `MachineInstr`'s successor list does not include the `MachineBasicBlock` for which the `blockaddress` `MachineOperand` refers (`bb.2`).
(Also, it's un-ergonomic that `blockaddress`es at the `MachineInstr` level seem to refer to `BasicBlock`s, and not `MachineBasicBlock`s. You have to call `MachineBasicBlock#getBasicBlock()`. I honestly don't like `blockaddress`es and wonder if we could make these all just have `BasicBlock`s or `MachineBasicBlock`s as operands?)
I'm going to check the other invariant I specified above now, and will report back on that.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D76961/new/
https://reviews.llvm.org/D76961
More information about the llvm-commits
mailing list