forked from OSchip/llvm-project
[CodeGen] Postprocess PHI nodes for callbr
When processing PHI nodes after a callbr, we need to make sure that the PHI nodes on the default branch are resolved after the callbr (inserted after INLINEASM_BR). The PHI node values on the indirect branches are processed before the INLINEASM_BR. Differential Revision: https://reviews.llvm.org/D86260
This commit is contained in:
parent
30514f0afa
commit
7f4c940bd0
|
@ -1084,9 +1084,8 @@ SDValue SelectionDAGBuilder::getControlRoot() {
|
|||
|
||||
void SelectionDAGBuilder::visit(const Instruction &I) {
|
||||
// Set up outgoing PHI node register values before emitting the terminator.
|
||||
if (I.isTerminator()) {
|
||||
HandlePHINodesInSuccessorBlocks(I.getParent());
|
||||
}
|
||||
if (I.isTerminator())
|
||||
HandlePHINodesInSuccessorBlocks(I.getParent(), true);
|
||||
|
||||
// Increase the SDNodeOrder if dealing with a non-debug instruction.
|
||||
if (!isa<DbgInfoIntrinsic>(I))
|
||||
|
@ -2839,6 +2838,9 @@ void SelectionDAGBuilder::visitCallBr(const CallBrInst &I) {
|
|||
visitInlineAsm(I);
|
||||
CopyToExportRegsIfNeeded(&I);
|
||||
|
||||
// Set up outgoing PHI node register values before emitting the branch.
|
||||
HandlePHINodesInSuccessorBlocks(I.getParent(), false);
|
||||
|
||||
// Retrieve successors.
|
||||
MachineBasicBlock *Return = FuncInfo.MBBMap[I.getDefaultDest()];
|
||||
|
||||
|
@ -9990,10 +9992,10 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
|
|||
/// directly add them, because expansion might result in multiple MBB's for one
|
||||
/// BB. As such, the start of the BB might correspond to a different MBB than
|
||||
/// the end.
|
||||
void
|
||||
SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
|
||||
void SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks(
|
||||
const BasicBlock *LLVMBB, bool Preprocess) {
|
||||
const Instruction *TI = LLVMBB->getTerminator();
|
||||
|
||||
const CallBrInst *CI = dyn_cast<CallBrInst>(TI);
|
||||
SmallPtrSet<MachineBasicBlock *, 4> SuccsHandled;
|
||||
|
||||
// Check PHI nodes in successors that expect a value to be available from this
|
||||
|
@ -10001,6 +10003,21 @@ SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
|
|||
for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) {
|
||||
const BasicBlock *SuccBB = TI->getSuccessor(succ);
|
||||
if (!isa<PHINode>(SuccBB->begin())) continue;
|
||||
|
||||
if (CI) {
|
||||
if (Preprocess) {
|
||||
// Don't push PHI node values back before an INLINEASM_BR instruction on
|
||||
// the default branch.
|
||||
if (SuccBB == CI->getDefaultDest())
|
||||
continue;
|
||||
} else {
|
||||
// Don't push PHI node values back after an INLINEASM_BR instruction on
|
||||
// the indirect branch.
|
||||
if (SuccBB != CI->getDefaultDest())
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
MachineBasicBlock *SuccMBB = FuncInfo.MBBMap[SuccBB];
|
||||
|
||||
// If this terminator has multiple identical successors (common for
|
||||
|
|
|
@ -783,7 +783,8 @@ private:
|
|||
void processIntegerCallValue(const Instruction &I,
|
||||
SDValue Value, bool IsSigned);
|
||||
|
||||
void HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
|
||||
void HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB,
|
||||
bool Preprocess);
|
||||
|
||||
void emitInlineAsmError(const CallBase &Call, const Twine &Message);
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=i686-- -verify-machineinstrs < %s | FileCheck %s
|
||||
|
||||
@var = global i32 0, align 4
|
||||
|
||||
define i32 @test1() {
|
||||
; CHECK-LABEL: test1:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: #APP
|
||||
; CHECK-NEXT: jmp .Ltmp0
|
||||
; CHECK-NEXT: #NO_APP
|
||||
; CHECK-NEXT: xorl %eax, %eax
|
||||
; CHECK-NEXT: # %bb.2:
|
||||
; CHECK-NEXT: retl
|
||||
; CHECK-NEXT: .Ltmp0: # Block address taken
|
||||
; CHECK-NEXT: .LBB0_1:
|
||||
; CHECK-NEXT: movl $1, %eax
|
||||
; CHECK-NEXT: retl
|
||||
callbr void asm sideeffect "jmp ${1:l}", "*m,X,~{dirflag},~{fpsr},~{flags}"(i32* nonnull @var, i8* blockaddress(@test1, %1))
|
||||
to label %2 [label %1]
|
||||
|
||||
1: ; preds = %0
|
||||
br label %2
|
||||
|
||||
2: ; preds = %0, %1
|
||||
%3 = phi i32 [ 1, %1 ], [ 0, %0 ]
|
||||
ret i32 %3
|
||||
}
|
Loading…
Reference in New Issue